drivers/media/pci/cobalt/cobalt-omnitek.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cobalt/cobalt-omnitek.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cobalt/cobalt-omnitek.c
Extension
.c
Size
8444 bytes
Lines
330
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 (cobalt->pci_32_bit) {
			WARN_ON((u64)addr >> 32);
			if ((u64)addr >> 32)
				return -EFAULT;
		}

		/* PCIe address */
		d->pci_l = addr & 0xffffffff;
		/* If dma_addr_t is 32 bits, then addr >> 32 is actually the
		   equivalent of addr >> 0 in gcc. So must cast to u64. */
		d->pci_h = (u64)addr >> 32;

		/* Sync to start of streaming frame */
		d->local = 0;
		d->reserved0 = 0;

		/* Transfer bytes */
		bytes = min(sg_dma_len(scatter_list) - offset,
				copy_bytes - copied);

		if (first) {
			if (to_pci)
				d->local = 0x11111111;
			first = false;
			if (sglen == 1) {
				/* Make sure there are always at least two
				 * descriptors */
				d->bytes = (bytes / 2) & ~3;
				d->reserved1 = 0;
				size -= d->bytes;
				copied += d->bytes;
				offset += d->bytes;
				addr += d->bytes;
				next += sizeof(struct sg_dma_descriptor);
				d->next_h = (u32)((u64)next >> 32);
				d->next_l = (u32)next |
					(to_pci ? WRITE_TO_PCI : 0);
				bytes -= d->bytes;
				d++;
				/* PCIe address */
				d->pci_l = addr & 0xffffffff;
				/* If dma_addr_t is 32 bits, then addr >> 32
				 * is actually the equivalent of addr >> 0 in
				 * gcc. So must cast to u64. */
				d->pci_h = (u64)addr >> 32;

				/* Sync to start of streaming frame */
				d->local = 0;
				d->reserved0 = 0;
			}
		}

		d->bytes = bytes;
		d->reserved1 = 0;
		size -= bytes;
		copied += bytes;
		offset += bytes;

		if (copied == copy_bytes) {
			while (copied < stride) {
				bytes = min(sg_dma_len(scatter_list) - offset,
						stride - copied);
				copied += bytes;
				offset += bytes;
				size -= bytes;
				if (sg_dma_len(scatter_list) == offset) {
					offset = 0;
					scatter_list = sg_next(scatter_list);
				}
			}
			copied = 0;
		} else {
			offset = 0;
			scatter_list = sg_next(scatter_list);
		}

		/* Next descriptor + control bits */
		next += sizeof(struct sg_dma_descriptor);
		if (size == 0) {
			/* Loopback to the first descriptor */
			d->next_h = (u32)((u64)desc->bus >> 32);
			d->next_l = (u32)desc->bus |
				(to_pci ? WRITE_TO_PCI : 0) | INTERRUPT_ENABLE;
			if (!to_pci)
				d->local = 0x22222222;
			desc->last_desc_virt = d;
		} else {
			d->next_h = (u32)((u64)next >> 32);
			d->next_l = (u32)next | (to_pci ? WRITE_TO_PCI : 0);
		}

Annotation

Implementation Notes