drivers/ata/libahci.c
Source file repositories/reference/linux-study-clean/drivers/ata/libahci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ata/libahci.c- Extension
.c- Size
- 73664 bytes
- Lines
- 2775
- Domain
- Driver Families
- Bucket
- drivers/ata
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/bitops.hlinux/kernel.hlinux/gfp.hlinux/module.hlinux/nospec.hlinux/blkdev.hlinux/delay.hlinux/interrupt.hlinux/dma-mapping.hlinux/device.hscsi/scsi_host.hscsi/scsi_cmnd.hlinux/libata.hlinux/pci.hahci.hlibata.h
Detected Declarations
function ahci_enable_ahcifunction ahci_rpm_get_portfunction ahci_rpm_get_portfunction ahci_show_host_capsfunction ahci_show_host_cap2function ahci_show_host_versionfunction ahci_show_port_cmdfunction ahci_read_em_bufferfunction ahci_store_em_bufferfunction ahci_show_em_supportedfunction ahci_save_initial_configfunction ahci_save_initial_configfunction for_each_set_bitfunction ahci_scr_offsetfunction ahci_scr_readfunction ahci_scr_writefunction ahci_start_enginefunction ahci_stop_enginefunction statefunction anymorefunction ahci_start_fis_rxfunction ahci_stop_fis_rxfunction ahci_power_upfunction ahci_set_lpmfunction ahci_power_downfunction ahci_start_portfunction ata_for_each_linkfunction ahci_deinit_portfunction ahci_reset_controllerfunction ahci_sw_activityfunction ahci_sw_activity_blinkfunction ahci_init_sw_activityfunction ahci_reset_emfunction ahci_transmit_led_messagefunction ahci_led_showfunction ata_for_each_linkfunction ahci_led_storefunction ahci_activity_storefunction ahci_activity_showfunction ahci_port_clear_pending_irqfunction ahci_port_initfunction ahci_init_controllerfunction ahci_dev_configfunction ahci_dev_classifyfunction ahci_fill_cmd_slotfunction ahci_kick_enginefunction ahci_exec_polled_cmdfunction ahci_do_softreset
Annotated Snippet
if (map_ports > ahci_nr_ports(cap)) {
dev_warn(dev,
"implemented port map (0x%lx) contains more ports than nr_ports (%u), using nr_ports\n",
port_map, ahci_nr_ports(cap));
port_map = 0;
}
}
/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
if (!port_map && vers < 0x10300) {
port_map = (1 << ahci_nr_ports(cap)) - 1;
dev_warn(dev, "forcing PORTS_IMPL to 0x%lx\n", port_map);
/* write the fixed up value to the PI register */
hpriv->saved_port_map = port_map;
}
/*
* Preserve the ports capabilities defined by the platform. Note there
* is no need in storing the rest of the P#.CMD fields since they are
* volatile.
*/
for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {
if (hpriv->saved_port_cap[i])
continue;
port_mmio = __ahci_port_base(hpriv, i);
hpriv->saved_port_cap[i] =
readl(port_mmio + PORT_CMD) & PORT_CMD_CAP;
}
/* record values to use during operation */
hpriv->cap = cap;
hpriv->cap2 = cap2;
hpriv->version = vers;
hpriv->port_map = port_map;
if (!hpriv->start_engine)
hpriv->start_engine = ahci_start_engine;
if (!hpriv->stop_engine)
hpriv->stop_engine = ahci_stop_engine;
if (!hpriv->irq_handler)
hpriv->irq_handler = ahci_single_level_irq_intr;
}
EXPORT_SYMBOL_GPL(ahci_save_initial_config);
/**
* ahci_restore_initial_config - Restore initial config
* @host: target ATA host
*
* Restore initial config stored by ahci_save_initial_config().
*
* LOCKING:
* None.
*/
static void ahci_restore_initial_config(struct ata_host *host)
{
struct ahci_host_priv *hpriv = host->private_data;
unsigned long port_map = hpriv->port_map;
void __iomem *mmio = hpriv->mmio;
void __iomem *port_mmio;
int i;
writel(hpriv->saved_cap, mmio + HOST_CAP);
if (hpriv->saved_cap2)
writel(hpriv->saved_cap2, mmio + HOST_CAP2);
writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {
port_mmio = __ahci_port_base(hpriv, i);
writel(hpriv->saved_port_cap[i], port_mmio + PORT_CMD);
}
}
static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
{
static const int offset[] = {
[SCR_STATUS] = PORT_SCR_STAT,
[SCR_CONTROL] = PORT_SCR_CTL,
[SCR_ERROR] = PORT_SCR_ERR,
[SCR_ACTIVE] = PORT_SCR_ACT,
[SCR_NOTIFICATION] = PORT_SCR_NTF,
};
struct ahci_host_priv *hpriv = ap->host->private_data;
if (sc_reg < ARRAY_SIZE(offset) &&
(sc_reg != SCR_NOTIFICATION || (hpriv->cap & HOST_CAP_SNTF)))
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/kernel.h`, `linux/gfp.h`, `linux/module.h`, `linux/nospec.h`, `linux/blkdev.h`, `linux/delay.h`, `linux/interrupt.h`.
- Detected declarations: `function ahci_enable_ahci`, `function ahci_rpm_get_port`, `function ahci_rpm_get_port`, `function ahci_show_host_caps`, `function ahci_show_host_cap2`, `function ahci_show_host_version`, `function ahci_show_port_cmd`, `function ahci_read_em_buffer`, `function ahci_store_em_buffer`, `function ahci_show_em_supported`.
- Atlas domain: Driver Families / drivers/ata.
- Implementation status: integration 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.