drivers/scsi/pm8001/pm8001_ctl.c
Source file repositories/reference/linux-study-clean/drivers/scsi/pm8001/pm8001_ctl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/pm8001/pm8001_ctl.c- Extension
.c- Size
- 32582 bytes
- Lines
- 1054
- 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.
- 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/firmware.hlinux/slab.hpm8001_sas.hpm8001_ctl.hpm8001_chips.h
Detected Declarations
struct flash_commandstruct error_fwfunction pm8001_ctl_mpi_interface_rev_showfunction controller_fatal_error_showfunction pm8001_ctl_fw_version_showfunction pm8001_ctl_ila_version_showfunction pm8001_ctl_inactive_fw_version_showfunction pm8001_ctl_max_out_io_showfunction pm8001_ctl_max_devices_showfunction pm8001_ctl_max_sg_list_showfunction show_sas_spec_support_statusfunction pm8001_ctl_sas_spec_support_showfunction pm8001_ctl_host_sas_address_showfunction pm8001_ctl_logging_level_showfunction pm8001_ctl_logging_level_storefunction pm8001_ctl_aap_log_showfunction pm8001_ctl_ib_queue_log_showfunction pm8001_ctl_ob_queue_log_showfunction pm8001_ctl_bios_version_showfunction event_log_size_showfunction pm8001_ctl_iop_log_showfunction pm8001_ctl_fatal_log_showfunction non_fatal_log_showfunction non_fatal_count_showfunction non_fatal_count_storefunction pm8001_ctl_gsm_log_showfunction pm8001_set_nvmdfunction pm8001_update_flashfunction pm8001_store_update_fwfunction pm8001_show_update_fwfunction ctl_mpi_state_showfunction ctl_hmi_error_showfunction ctl_raae_count_showfunction ctl_iop0_count_showfunction ctl_iop1_count_show
Annotated Snippet
struct flash_command {
u8 command[8] __nonstring;
int code;
};
static const struct flash_command flash_command_table[] = {
{"set_nvmd", FLASH_CMD_SET_NVMD},
{"update", FLASH_CMD_UPDATE},
{"", FLASH_CMD_NONE} /* Last entry should be NULL. */
};
struct error_fw {
char *reason;
int err_code;
};
static const struct error_fw flash_error_table[] = {
{"Failed to open fw image file", FAIL_OPEN_BIOS_FILE},
{"image header mismatch", FLASH_UPDATE_HDR_ERR},
{"image offset mismatch", FLASH_UPDATE_OFFSET_ERR},
{"image CRC Error", FLASH_UPDATE_CRC_ERR},
{"image length Error.", FLASH_UPDATE_LENGTH_ERR},
{"Failed to program flash chip", FLASH_UPDATE_HW_ERR},
{"Flash chip not supported.", FLASH_UPDATE_DNLD_NOT_SUPPORTED},
{"Flash update disabled.", FLASH_UPDATE_DISABLED},
{"Flash in progress", FLASH_IN_PROGRESS},
{"Image file size Error", FAIL_FILE_SIZE},
{"Input parameter error", FAIL_PARAMETERS},
{"Out of memory", FAIL_OUT_MEMORY},
{"OK", 0} /* Last entry err_code = 0. */
};
static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha)
{
struct pm8001_ioctl_payload *payload;
DECLARE_COMPLETION_ONSTACK(completion);
u8 *ioctlbuffer;
int ret;
u32 length = 1024 * 5 + sizeof(*payload) - 1;
if (pm8001_ha->fw_image->size > 4096) {
pm8001_ha->fw_status = FAIL_FILE_SIZE;
return -EFAULT;
}
ioctlbuffer = kzalloc(length, GFP_KERNEL);
if (!ioctlbuffer) {
pm8001_ha->fw_status = FAIL_OUT_MEMORY;
return -ENOMEM;
}
payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
pm8001_ha->fw_image->size);
payload->wr_length = pm8001_ha->fw_image->size;
payload->id = 0;
payload->minor_function = 0x1;
pm8001_ha->nvmd_completion = &completion;
ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
if (ret) {
pm8001_ha->fw_status = FAIL_OUT_MEMORY;
goto out;
}
wait_for_completion(&completion);
out:
kfree(ioctlbuffer);
return ret;
}
static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
{
struct pm8001_ioctl_payload *payload;
DECLARE_COMPLETION_ONSTACK(completion);
u8 *ioctlbuffer;
struct fw_control_info *fwControl;
__be32 partitionSizeTmp;
u32 partitionSize;
u32 loopNumber, loopcount;
struct pm8001_fw_image_header *image_hdr;
u32 sizeRead = 0;
u32 ret = 0;
u32 length = 1024 * 16 + sizeof(*payload) - 1;
u32 fc_len;
u8 *read_buf;
if (pm8001_ha->fw_image->size < 28) {
pm8001_ha->fw_status = FAIL_FILE_SIZE;
return -EFAULT;
}
ioctlbuffer = kzalloc(length, GFP_KERNEL);
if (!ioctlbuffer) {
Annotation
- Immediate include surface: `linux/firmware.h`, `linux/slab.h`, `pm8001_sas.h`, `pm8001_ctl.h`, `pm8001_chips.h`.
- Detected declarations: `struct flash_command`, `struct error_fw`, `function pm8001_ctl_mpi_interface_rev_show`, `function controller_fatal_error_show`, `function pm8001_ctl_fw_version_show`, `function pm8001_ctl_ila_version_show`, `function pm8001_ctl_inactive_fw_version_show`, `function pm8001_ctl_max_out_io_show`, `function pm8001_ctl_max_devices_show`, `function pm8001_ctl_max_sg_list_show`.
- 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.
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.