drivers/media/pci/cx18/cx18-firmware.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/cx18/cx18-firmware.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/cx18/cx18-firmware.c- Extension
.c- Size
- 14260 bytes
- Lines
- 446
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
cx18-driver.hcx18-io.hcx18-scb.hcx18-irq.hcx18-firmware.hcx18-cards.hlinux/firmware.h
Detected Declarations
struct cx18_apu_rom_seghdrfunction load_cpu_fw_directfunction load_apu_fw_directfunction cx18_halt_firmwarefunction cx18_init_powerfunction cx18_init_memoryfunction cx18_firmware_init
Annotated Snippet
struct cx18_apu_rom_seghdr {
u32 sync1;
u32 sync2;
u32 addr;
u32 size;
};
static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
{
const struct firmware *fw = NULL;
int i, j;
unsigned size;
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
}
src = (const u32 *)fw->data;
for (i = 0; i < fw->size; i += 4096) {
cx18_setup_page(cx, i);
for (j = i; j < fw->size && j < i + 4096; j += 4) {
/* no need for endianness conversion on the ppc */
cx18_raw_writel(cx, *src, dst);
if (cx18_raw_readl(cx, dst) != *src) {
CX18_ERR("Mismatch at offset %x\n", i);
release_firmware(fw);
cx18_setup_page(cx, 0);
return -EIO;
}
dst++;
src++;
}
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware (%zu bytes)\n", fn, fw->size);
size = fw->size;
release_firmware(fw);
cx18_setup_page(cx, SCB_OFFSET);
return size;
}
static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 *entry_addr)
{
const struct firmware *fw = NULL;
int i, j;
unsigned size;
const u32 *src;
struct cx18_apu_rom_seghdr seghdr;
const u8 *vers;
u32 offset = 0;
u32 apu_version = 0;
int sz;
if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
cx18_setup_page(cx, 0);
return -ENOMEM;
}
*entry_addr = 0;
src = (const u32 *)fw->data;
vers = fw->data + sizeof(seghdr);
sz = fw->size;
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
while (offset + sizeof(seghdr) < fw->size) {
const __le32 *shptr = (__force __le32 *)src + offset / 4;
seghdr.sync1 = le32_to_cpu(shptr[0]);
seghdr.sync2 = le32_to_cpu(shptr[1]);
seghdr.addr = le32_to_cpu(shptr[2]);
seghdr.size = le32_to_cpu(shptr[3]);
offset += sizeof(seghdr);
if (seghdr.sync1 != APU_ROM_SYNC1 ||
seghdr.sync2 != APU_ROM_SYNC2) {
offset += seghdr.size;
continue;
}
CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
seghdr.addr + seghdr.size - 1);
if (*entry_addr == 0)
*entry_addr = seghdr.addr;
Annotation
- Immediate include surface: `cx18-driver.h`, `cx18-io.h`, `cx18-scb.h`, `cx18-irq.h`, `cx18-firmware.h`, `cx18-cards.h`, `linux/firmware.h`.
- Detected declarations: `struct cx18_apu_rom_seghdr`, `function load_cpu_fw_direct`, `function load_apu_fw_direct`, `function cx18_halt_firmware`, `function cx18_init_power`, `function cx18_init_memory`, `function cx18_firmware_init`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.