drivers/parisc/lba_pci.c
Source file repositories/reference/linux-study-clean/drivers/parisc/lba_pci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/parisc/lba_pci.c- Extension
.c- Size
- 51917 bytes
- Lines
- 1761
- Domain
- Driver Families
- Bucket
- drivers/parisc
- 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/delay.hlinux/types.hlinux/kernel.hlinux/spinlock.hlinux/init.hlinux/pci.hlinux/ioport.hlinux/slab.hasm/byteorder.hasm/pdc.hasm/pdcpat.hasm/page.hasm/ropes.hasm/hardware.hasm/parisc-device.hasm/io.hiommu.h
Detected Declarations
function LBAfunction lba_device_presentfunction errorfunction lba_rd_cfgfunction elroy_cfg_readfunction lba_wr_cfgfunction elroy_cfg_writefunction mercury_cfg_readfunction mercury_cfg_writefunction lba_bios_initfunction truncate_pat_collisionfunction extend_lmmio_lenfunction pcibios_allocate_bridge_resourcesfunction pcibios_allocate_bus_resourcesfunction do_pci_scan_busfunction pci_alloc_primary_busfunction list_for_each_entryfunction pci_setup_bridgefunction lba_pat_resourcesfunction lba_legacy_resourcesfunction codefunction chipfunction prunefunction pci_initfunction lockingfunction machinesfunction quirk_diva_aux_disablefunction quirk_tosca_aux_disable
Annotated Snippet
if ((error_status & 0x1f) != 0) { \
/* \
* Fail the config read request. \
*/ \
error = 1; \
if ((error_status & LBA_FATAL_ERROR) == 0) { \
/* \
* Clear error status (if fatal bit not set) by setting \
* clear error log bit (CL). \
*/ \
WRITE_REG32(status_control | CLEAR_ERRLOG, base + LBA_STAT_CTL); \
} \
} \
}
#define LBA_CFG_TR4_ADDR_SETUP(d, addr) \
WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR);
#define LBA_CFG_ADDR_SETUP(d, addr) { \
WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
/* \
* Read address register to ensure that LBA is the bus master, \
* which implies that DMA traffic has stopped when DMA arb is off. \
*/ \
lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
}
#define LBA_CFG_RESTORE(d, base) { \
/* \
* Restore status control register (turn off clear enable). \
*/ \
WRITE_REG32(status_control, base + LBA_STAT_CTL); \
/* \
* Restore error config register (turn off smart mode). \
*/ \
WRITE_REG32(error_config, base + LBA_ERROR_CONFIG); \
/* \
* Restore arb mask register (reenables DMA arbitration). \
*/ \
WRITE_REG32(arb_mask, base + LBA_ARB_MASK); \
}
static unsigned int
lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
{
u32 data = ~0U;
int error = 0;
u32 arb_mask = 0; /* used by LBA_CFG_SETUP/RESTORE */
u32 error_config = 0; /* used by LBA_CFG_SETUP/RESTORE */
u32 status_control = 0; /* used by LBA_CFG_SETUP/RESTORE */
LBA_CFG_SETUP(d, tok);
LBA_CFG_PROBE(d, tok);
LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
if (!error) {
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
LBA_CFG_ADDR_SETUP(d, tok | reg);
switch (size) {
case 1: data = (u32) READ_REG8(data_reg + (reg & 3)); break;
case 2: data = (u32) READ_REG16(data_reg+ (reg & 2)); break;
case 4: data = READ_REG32(data_reg); break;
}
}
LBA_CFG_RESTORE(d, d->hba.base_addr);
return(data);
}
static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
{
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
u32 tok = LBA_CFG_TOK(local_bus, devfn);
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
if ((pos > 255) || (devfn > 255))
return -EINVAL;
/* FIXME: B2K/C3600 workaround is always use old method... */
/* if (!LBA_SKIP_PROBE(d)) */ {
/* original - Generate config cycle on broken elroy
with risk we will miss PCI bus errors. */
*data = lba_rd_cfg(d, tok, pos, size);
DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data);
return 0;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/types.h`, `linux/kernel.h`, `linux/spinlock.h`, `linux/init.h`, `linux/pci.h`, `linux/ioport.h`, `linux/slab.h`.
- Detected declarations: `function LBA`, `function lba_device_present`, `function error`, `function lba_rd_cfg`, `function elroy_cfg_read`, `function lba_wr_cfg`, `function elroy_cfg_write`, `function mercury_cfg_read`, `function mercury_cfg_write`, `function lba_bios_init`.
- Atlas domain: Driver Families / drivers/parisc.
- 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.