drivers/media/pci/zoran/videocodec.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/zoran/videocodec.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/zoran/videocodec.c
Extension
.c
Size
6210 bytes
Lines
279
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct attached_list {
	struct videocodec *codec;
	struct attached_list *next;
};

struct codec_list {
	const struct videocodec *codec;
	int attached;
	struct attached_list *list;
	struct codec_list *next;
};

static struct codec_list *codeclist_top;

/* ================================================= */
/* function prototypes of the master/slave interface */
/* ================================================= */

struct videocodec *videocodec_attach(struct videocodec_master *master)
{
	struct codec_list *h = codeclist_top;
	struct zoran *zr;
	struct attached_list *a, *ptr;
	struct videocodec *codec;
	int res;

	if (!master) {
		pr_err("%s: no data\n", __func__);
		return NULL;
	}

	zr = videocodec_master_to_zoran(master);

	zrdev_dbg(zr, "%s: '%s', flags %lx, magic %lx\n", __func__,
		  master->name, master->flags, master->magic);

	if (!h) {
		zrdev_err(zr, "%s: no device available\n", __func__);
		return NULL;
	}

	while (h) {
		// attach only if the slave has at least the flags
		// expected by the master
		if ((master->flags & h->codec->flags) == master->flags) {
			zrdev_dbg(zr, "%s: try '%s'\n", __func__, h->codec->name);

			codec = kmemdup(h->codec, sizeof(struct videocodec), GFP_KERNEL);
			if (!codec)
				goto out_kfree;

			res = strlen(codec->name);
			snprintf(codec->name + res, sizeof(codec->name) - res, "[%d]", h->attached);
			codec->master_data = master;
			res = codec->setup(codec);
			if (res == 0) {
				zrdev_dbg(zr, "%s: '%s'\n", __func__, codec->name);
				ptr = kzalloc_obj(*ptr);
				if (!ptr)
					goto out_kfree;
				ptr->codec = codec;

				a = h->list;
				if (!a) {
					h->list = ptr;
					zrdev_dbg(zr, "videocodec: first element\n");
				} else {
					while (a->next)
						a = a->next;	// find end
					a->next = ptr;
					zrdev_dbg(zr, "videocodec: in after '%s'\n",
						  h->codec->name);
				}

				h->attached += 1;
				return codec;
			}
			kfree(codec);
		}
		h = h->next;
	}

	zrdev_err(zr, "%s: no codec found!\n", __func__);
	return NULL;

 out_kfree:
	kfree(codec);
	return NULL;
}

Annotation

Implementation Notes