drivers/media/pci/saa7164/saa7164-fw.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/saa7164/saa7164-fw.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/saa7164/saa7164-fw.c
Extension
.c
Size
15816 bytes
Lines
598
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 fw_header {
	u32	firmwaresize;
	u32	bslsize;
	u32	reserved;
	u32	version;
};

static int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
{
	u32 timeout = SAA_DEVICE_TIMEOUT;
	while ((saa7164_readl(reg) & 0x01) == 0) {
		timeout -= 10;
		if (timeout == 0) {
			printk(KERN_ERR "%s() timeout (no d/l ack)\n",
				__func__);
			return -EBUSY;
		}
		msleep(100);
	}

	return 0;
}

static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
{
	u32 timeout = SAA_DEVICE_TIMEOUT;
	while (saa7164_readl(reg) & 0x01) {
		timeout -= 10;
		if (timeout == 0) {
			printk(KERN_ERR "%s() timeout (no d/l clr)\n",
				__func__);
			return -EBUSY;
		}
		msleep(100);
	}

	return 0;
}

/* TODO: move dlflags into dev-> and change to write/readl/b */
/* TODO: Excessive levels of debug */
static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
				 u32 dlflags, u8 __iomem *dst, u32 dstsize)
{
	u32 reg, timeout, offset;
	u8 *srcbuf = NULL;
	int ret;

	u32 dlflag = dlflags;
	u32 dlflag_ack = dlflag + 4;
	u32 drflag = dlflag_ack + 4;
	u32 drflag_ack = drflag + 4;
	u32 bleflag = drflag_ack + 4;

	dprintk(DBGLVL_FW,
		"%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
		__func__, src, srcsize, dlflags, dst, dstsize);

	if ((src == NULL) || (dst == NULL)) {
		ret = -EIO;
		goto out;
	}

	srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
	if (NULL == srcbuf) {
		ret = -ENOMEM;
		goto out;
	}

	if (srcsize > (4*1048576)) {
		ret = -ENOMEM;
		goto out;
	}

	memcpy(srcbuf, src, srcsize);

	dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
	dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
	dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
	dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
	dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);

	reg = saa7164_readl(dlflag);
	dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
	if (reg == 1)
		dprintk(DBGLVL_FW,
			"%s() Download flag already set, please reboot\n",
			__func__);

	/* Indicate download start */

Annotation

Implementation Notes