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

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

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/saa7164/saa7164-bus.c
Extension
.c
Size
13745 bytes
Lines
468
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

if (timeout-- == 0) {
			printk(KERN_ERR "%s() bus timeout\n", __func__);
			ret = SAA_ERR_NO_RESOURCES;
			goto out;
		}

		/* TODO: Review this delay, efficient? */
		/* Wait, allowing the hardware fetch time */
		mdelay(1);

		/* Check the space usage again */
		curr_srp = saa7164_readl(bus->m_dwSetReadPos);

		/* Deal with ring wrapping issues */
		if (curr_srp > curr_swp)
			/* Deal with the wrapped ring */
			free_write_space = curr_srp - curr_swp;
		else
			/* Read didn't wrap around the buffer */
			free_write_space = (curr_srp + bus->m_dwSizeSetRing) -
				curr_swp;

	}

	/* Calculate the new write position */
	new_swp = curr_swp + bytes_to_write;

	dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
	dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
		bus->m_dwSizeSetRing);

	/*
	 * Make a copy of msg->size before it is converted to le16 since it is
	 * used in the code below.
	 */
	size = msg->size;
	/* Convert to le16/le32 */
	msg->size = (__force u16)cpu_to_le16(msg->size);
	msg->command = (__force u32)cpu_to_le32(msg->command);
	msg->controlselector = (__force u16)cpu_to_le16(msg->controlselector);

	/* Mental Note: line 462 tmmhComResBusPCIe.cpp */

	/* Check if we're going to wrap again */
	if (new_swp > bus->m_dwSizeSetRing) {

		/* Ring wraps */
		new_swp -= bus->m_dwSizeSetRing;

		space_rem = bus->m_dwSizeSetRing - curr_swp;

		dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
			space_rem);

		dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
			(u32)sizeof(*msg));

		if (space_rem < sizeof(*msg)) {
			dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);

			/* Split the msg into pieces as the ring wraps */
			memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, space_rem);
			memcpy_toio(bus->m_pdwSetRing, (u8 *)msg + space_rem,
				sizeof(*msg) - space_rem);

			memcpy_toio(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
				buf, size);

		} else if (space_rem == sizeof(*msg)) {
			dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);

			/* Additional data at the beginning of the ring */
			memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
			memcpy_toio(bus->m_pdwSetRing, buf, size);

		} else {
			/* Additional data wraps around the ring */
			memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
			if (size > 0) {
				memcpy_toio(bus->m_pdwSetRing + curr_swp +
					sizeof(*msg), buf, space_rem -
					sizeof(*msg));
				memcpy_toio(bus->m_pdwSetRing, (u8 *)buf +
					space_rem - sizeof(*msg),
					bytes_to_write - space_rem);
			}

		}

	} /* (new_swp > bus->m_dwSizeSetRing) */

Annotation

Implementation Notes