drivers/accel/habanalabs/common/firmware_if.c
Source file repositories/reference/linux-study-clean/drivers/accel/habanalabs/common/firmware_if.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accel/habanalabs/common/firmware_if.c- Extension
.c- Size
- 93636 bytes
- Lines
- 3338
- Domain
- Driver Families
- Bucket
- drivers/accel
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
habanalabs.hlinux/habanalabs/hl_boot_if.hlinux/pci.hlinux/firmware.hlinux/crc32.hlinux/slab.hlinux/ctype.hlinux/vmalloc.htrace/events/habanalabs.h
Detected Declarations
function hl_fw_version_cmpfunction extract_u32_until_given_charfunction hl_get_sw_major_minor_subminorfunction hl_get_preboot_major_minorfunction hl_request_fwfunction hl_release_firmwarefunction hl_fw_copy_fw_to_devicefunction hl_fw_copy_msg_to_devicefunction hl_fw_load_fw_to_devicefunction hl_fw_send_pci_access_msgfunction hl_fw_send_cpu_messagefunction hl_fw_unmask_irqfunction hl_fw_unmask_irq_arrfunction hl_fw_test_cpu_queuefunction hl_fw_cpu_accessible_dma_pool_freefunction hl_fw_send_soft_resetfunction hl_fw_send_device_activityfunction hl_fw_send_heartbeatfunction fw_report_boot_dev0function fw_report_boot_dev1function fw_read_errorsfunction hl_fw_cpucp_info_getfunction hl_fw_send_msi_info_msgfunction hl_fw_cpucp_handshakefunction hl_fw_get_eeprom_datafunction hl_fw_get_monitor_dumpfunction hl_fw_cpucp_pci_counters_getfunction hl_fw_cpucp_total_energy_getfunction get_used_pll_indexfunction hl_fw_cpucp_pll_info_getfunction hl_fw_cpucp_power_getfunction hl_fw_dram_replaced_row_getfunction hl_fw_dram_pending_row_getfunction hl_fw_cpucp_engine_core_asid_setfunction hl_fw_ask_hard_reset_without_linuxfunction hl_fw_ask_halt_machine_without_linuxfunction detect_cpu_boot_statusfunction hl_fw_wait_preboot_readyfunction hl_fw_read_preboot_capsfunction hl_fw_static_read_device_fw_versionfunction hl_fw_preboot_update_statefunction hl_fw_static_read_preboot_statusfunction hl_fw_read_preboot_statusfunction hl_fw_dynamic_report_error_statusfunction hl_fw_dynamic_send_cmdfunction hl_fw_dynamic_extract_fw_responsefunction occursfunction CPU
Annotated Snippet
if (!hl_device_operational(hdev, NULL) && !hdev->reset_info.in_compute_reset) {
dev_dbg(hdev->dev, "Device CPU packet timeout (0x%x) due to FW reset\n",
tmp);
} else {
struct hl_bd *bd = queue->kernel_address;
bd += hl_pi_2_offset(pi);
dev_err(hdev->dev, "Device CPU packet timeout (status = 0x%x)\n"
"Pkt info[%u]: dma_addr: 0x%llx, kernel_addr: %p, len:0x%x, ctl: 0x%x, ptr:0x%llx, dram_bd:%u\n",
tmp, pi, pkt_dma_addr, (void *)pkt, bd->len, bd->ctl, bd->ptr,
queue->dram_bd);
}
hdev->device_cpu_disabled = true;
goto out;
}
tmp = le32_to_cpu(pkt->ctl);
fw_rc = (tmp & CPUCP_PKT_CTL_RC_MASK) >> CPUCP_PKT_CTL_RC_SHIFT;
if (fw_rc) {
opcode = (tmp & CPUCP_PKT_CTL_OPCODE_MASK) >> CPUCP_PKT_CTL_OPCODE_SHIFT;
if (!prop->supports_advanced_cpucp_rc) {
dev_dbg(hdev->dev, "F/W ERROR %d for CPU packet %d\n", rc, opcode);
rc = -EIO;
goto scrub_descriptor;
}
switch (fw_rc) {
case cpucp_packet_invalid:
dev_err(hdev->dev,
"CPU packet %d is not supported by F/W\n", opcode);
break;
case cpucp_packet_fault:
dev_err(hdev->dev,
"F/W failed processing CPU packet %d\n", opcode);
break;
case cpucp_packet_invalid_pkt:
dev_dbg(hdev->dev,
"CPU packet %d is not supported by F/W\n", opcode);
break;
case cpucp_packet_invalid_params:
dev_err(hdev->dev,
"F/W reports invalid parameters for CPU packet %d\n", opcode);
break;
default:
dev_err(hdev->dev,
"Unknown F/W ERROR %d for CPU packet %d\n", rc, opcode);
}
/* propagate the return code from the f/w to the callers who want to check it */
if (result)
*result = fw_rc;
rc = -EIO;
} else if (result) {
*result = le64_to_cpu(pkt->result);
}
scrub_descriptor:
/* Scrub previous buffer descriptor 'ctl' field which contains the
* previous PI value written during packet submission.
* We must do this or else F/W can read an old value upon queue wraparound.
*/
sent_bd = queue->kernel_address;
sent_bd += hl_pi_2_offset(pi);
sent_bd->ctl = cpu_to_le32(UINT_MAX);
out:
mutex_unlock(&hdev->send_cpu_message_lock);
hl_cpu_accessible_dma_pool_free(hdev, size, pkt);
return rc;
}
int hl_fw_unmask_irq(struct hl_device *hdev, u16 event_type)
{
struct cpucp_packet pkt;
u64 result;
int rc;
memset(&pkt, 0, sizeof(pkt));
pkt.ctl = cpu_to_le32(CPUCP_PACKET_UNMASK_RAZWI_IRQ <<
CPUCP_PKT_CTL_OPCODE_SHIFT);
pkt.value = cpu_to_le64(event_type);
Annotation
- Immediate include surface: `habanalabs.h`, `linux/habanalabs/hl_boot_if.h`, `linux/pci.h`, `linux/firmware.h`, `linux/crc32.h`, `linux/slab.h`, `linux/ctype.h`, `linux/vmalloc.h`.
- Detected declarations: `function hl_fw_version_cmp`, `function extract_u32_until_given_char`, `function hl_get_sw_major_minor_subminor`, `function hl_get_preboot_major_minor`, `function hl_request_fw`, `function hl_release_firmware`, `function hl_fw_copy_fw_to_device`, `function hl_fw_copy_msg_to_device`, `function hl_fw_load_fw_to_device`, `function hl_fw_send_pci_access_msg`.
- Atlas domain: Driver Families / drivers/accel.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.