drivers/scsi/pm8001/pm8001_hwi.c
Source file repositories/reference/linux-study-clean/drivers/scsi/pm8001/pm8001_hwi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/pm8001/pm8001_hwi.c- Extension
.c- Size
- 157383 bytes
- Lines
- 4780
- Domain
- Driver Families
- Bucket
- drivers/scsi
- 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
linux/slab.hpm8001_sas.hpm8001_hwi.hpm8001_chips.hpm8001_ctl.hpm80xx_tracepoints.h
Detected Declarations
function read_main_config_tablefunction read_general_status_tablefunction read_inbnd_queue_tablefunction read_outbnd_queue_tablefunction init_default_table_valuesfunction update_main_config_tablefunction update_inbnd_queue_tablefunction update_outbnd_queue_tablefunction pm8001_bar4_shiftfunction mpi_set_phys_g3_with_sscfunction mpi_set_open_retry_interval_regfunction mpi_init_checkfunction check_fw_readyfunction init_pci_device_addressesfunction pm8001_chip_initfunction pm8001_chip_post_initfunction soft_reset_ready_checkfunction pm8001_chip_soft_rstfunction pm8001_hw_chip_rstfunction pm8001_chip_iounmapfunction pm8001_chip_interrupt_enablefunction pm8001_chip_interrupt_disablefunction pm8001_mpi_msg_free_getfunction le32_to_cpufunction pm8001_mpi_build_cmdfunction pm8001_mpi_msg_free_setfunction pm8001_mpi_msg_consumefunction pm8001_work_fnfunction pm8001_handle_eventfunction mpi_ssp_completionfunction mpi_ssp_eventfunction mpi_sata_completionfunction mpi_sata_eventfunction mpi_smp_completionfunction pm8001_mpi_set_dev_state_respfunction pm8001_mpi_set_nvmd_respfunction pm8001_mpi_get_nvmd_respfunction pm8001_mpi_local_phy_ctlfunction eventfunction pm8001_get_lrate_modefunction pm8001_get_attached_sas_addrfunction pm8001_hw_event_ack_reqfunction hw_event_sas_phy_upfunction hw_event_sata_phy_upfunction hw_event_phy_downfunction pm8001_mpi_reg_respfunction pm8001_mpi_dereg_respfunction pm8001_mpi_fw_flash_update_resp
Annotated Snippet
if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
pm8001_dbg(pm8001_ha, FAIL,
"Shift Bar4 to 0x%x failed\n",
GSM_SM_BASE);
return -1;
}
}
/* check the firmware status */
if (-1 == check_fw_ready(pm8001_ha)) {
pm8001_dbg(pm8001_ha, FAIL, "Firmware is not ready!\n");
return -EBUSY;
}
/* Initialize pci space address eg: mpi offset */
init_pci_device_addresses(pm8001_ha);
init_default_table_values(pm8001_ha);
read_main_config_table(pm8001_ha);
read_general_status_table(pm8001_ha);
read_inbnd_queue_table(pm8001_ha);
read_outbnd_queue_table(pm8001_ha);
/* update main config table ,inbound table and outbound table */
update_main_config_table(pm8001_ha);
for (i = 0; i < pm8001_ha->max_q_num; i++)
update_inbnd_queue_table(pm8001_ha, i);
for (i = 0; i < pm8001_ha->max_q_num; i++)
update_outbnd_queue_table(pm8001_ha, i);
/* 8081 controller donot require these operations */
if (deviceid != 0x8081 && deviceid != 0x0042) {
mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
/* 7->130ms, 34->500ms, 119->1.5s */
mpi_set_open_retry_interval_reg(pm8001_ha, 119);
}
/* notify firmware update finished and check initialization status */
if (0 == mpi_init_check(pm8001_ha)) {
pm8001_dbg(pm8001_ha, INIT, "MPI initialize successful!\n");
} else
return -EBUSY;
/*This register is a 16-bit timer with a resolution of 1us. This is the
timer used for interrupt delay/coalescing in the PCIe Application Layer.
Zero is not a valid value. A value of 1 in the register will cause the
interrupts to be normal. A value greater than 1 will cause coalescing
delays.*/
pm8001_cw32(pm8001_ha, 1, 0x0033c0, 0x1);
pm8001_cw32(pm8001_ha, 1, 0x0033c4, 0x0);
return 0;
}
static void pm8001_chip_post_init(struct pm8001_hba_info *pm8001_ha)
{
}
static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
{
u32 max_wait_count;
u32 value;
u32 gst_len_mpistate;
u16 deviceid;
pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
if (deviceid == 0x8081 || deviceid == 0x0042) {
if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) {
pm8001_dbg(pm8001_ha, FAIL,
"Shift Bar4 to 0x%x failed\n",
GSM_SM_BASE);
return -1;
}
}
init_pci_device_addresses(pm8001_ha);
/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
table is stop */
pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_RESET);
/* wait until Inbound DoorBell Clear Register toggled */
max_wait_count = 1 * 1000 * 1000;/* 1 sec */
do {
udelay(1);
value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
value &= SPC_MSGU_CFG_TABLE_RESET;
} while ((value != 0) && (--max_wait_count));
if (!max_wait_count) {
pm8001_dbg(pm8001_ha, FAIL, "TIMEOUT:IBDB value/=0x%x\n",
value);
return -1;
}
/* check the MPI-State for termination in progress */
/* wait until Inbound DoorBell Clear Register toggled */
max_wait_count = 1 * 1000 * 1000; /* 1 sec */
do {
udelay(1);
Annotation
- Immediate include surface: `linux/slab.h`, `pm8001_sas.h`, `pm8001_hwi.h`, `pm8001_chips.h`, `pm8001_ctl.h`, `pm80xx_tracepoints.h`.
- Detected declarations: `function read_main_config_table`, `function read_general_status_table`, `function read_inbnd_queue_table`, `function read_outbnd_queue_table`, `function init_default_table_values`, `function update_main_config_table`, `function update_inbnd_queue_table`, `function update_outbnd_queue_table`, `function pm8001_bar4_shift`, `function mpi_set_phys_g3_with_ssc`.
- Atlas domain: Driver Families / drivers/scsi.
- 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.