drivers/scsi/qla4xxx/ql4_nvram.c
Source file repositories/reference/linux-study-clean/drivers/scsi/qla4xxx/ql4_nvram.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/qla4xxx/ql4_nvram.c- Extension
.c- Size
- 6269 bytes
- Lines
- 256
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
ql4_def.hql4_glbl.hql4_dbg.hql4_inline.h
Detected Declarations
function Copyrightfunction eeprom_sizefunction eeprom_no_addr_bitsfunction eeprom_no_data_bitsfunction fm93c56a_selectfunction fm93c56a_cmdfunction fm93c56a_deselectfunction fm93c56a_datainfunction eeprom_readwordfunction rd_nvram_wordfunction rd_nvram_bytefunction qla4xxx_is_nvram_configuration_validfunction ql4xxx_sem_spinlockfunction ql4xxx_sem_unlockfunction ql4xxx_sem_lock
Annotated Snippet
if (previousBit != dataBit) {
/*
* If the bit changed, then change the DO state to
* match.
*/
eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha);
previousBit = dataBit;
}
eeprom_cmd(ha->eeprom_cmd_data | dataBit |
AUBURN_EEPROM_CLK_RISE, ha);
eeprom_cmd(ha->eeprom_cmd_data | dataBit |
AUBURN_EEPROM_CLK_FALL, ha);
cmd = cmd << 1;
}
mask = 1 << (eeprom_no_addr_bits(ha) - 1);
/* Force the previous data bit to be different. */
previousBit = 0xffff;
for (i = 0; i < eeprom_no_addr_bits(ha); i++) {
dataBit = addr & mask ? AUBURN_EEPROM_DO_1 :
AUBURN_EEPROM_DO_0;
if (previousBit != dataBit) {
/*
* If the bit changed, then change the DO state to
* match.
*/
eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha);
previousBit = dataBit;
}
eeprom_cmd(ha->eeprom_cmd_data | dataBit |
AUBURN_EEPROM_CLK_RISE, ha);
eeprom_cmd(ha->eeprom_cmd_data | dataBit |
AUBURN_EEPROM_CLK_FALL, ha);
addr = addr << 1;
}
return 1;
}
static int fm93c56a_deselect(struct scsi_qla_host * ha)
{
ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000;
eeprom_cmd(ha->eeprom_cmd_data, ha);
return 1;
}
static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value)
{
int i;
int data = 0;
int dataBit;
/* Read the data bits
* The first bit is a dummy. Clock right over it. */
for (i = 0; i < eeprom_no_data_bits(ha); i++) {
eeprom_cmd(ha->eeprom_cmd_data |
AUBURN_EEPROM_CLK_RISE, ha);
eeprom_cmd(ha->eeprom_cmd_data |
AUBURN_EEPROM_CLK_FALL, ha);
dataBit = (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0;
data = (data << 1) | dataBit;
}
*value = data;
return 1;
}
static int eeprom_readword(int eepromAddr, u16 * value,
struct scsi_qla_host * ha)
{
fm93c56a_select(ha);
fm93c56a_cmd(ha, FM93C56A_READ, eepromAddr);
fm93c56a_datain(ha, value);
fm93c56a_deselect(ha);
return 1;
}
/* Hardware_lock must be set before calling */
u16 rd_nvram_word(struct scsi_qla_host * ha, int offset)
{
u16 val = 0;
/* NOTE: NVRAM uses half-word addresses */
eeprom_readword(offset, &val, ha);
return val;
Annotation
- Immediate include surface: `ql4_def.h`, `ql4_glbl.h`, `ql4_dbg.h`, `ql4_inline.h`.
- Detected declarations: `function Copyright`, `function eeprom_size`, `function eeprom_no_addr_bits`, `function eeprom_no_data_bits`, `function fm93c56a_select`, `function fm93c56a_cmd`, `function fm93c56a_deselect`, `function fm93c56a_datain`, `function eeprom_readword`, `function rd_nvram_word`.
- 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.