drivers/ata/ahci_dwc.c
Source file repositories/reference/linux-study-clean/drivers/ata/ahci_dwc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ata/ahci_dwc.c- Extension
.c- Size
- 11327 bytes
- Lines
- 433
- Domain
- Driver Families
- Bucket
- drivers/ata
- 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.
- 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/ahci_platform.hlinux/bitfield.hlinux/bits.hlinux/clk.hlinux/device.hlinux/kernel.hlinux/libata.hlinux/log2.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/pm.hahci.h
Detected Declarations
struct ahci_dwc_plat_datastruct ahci_dwc_host_privfunction ahci_dwc_check_capfunction for_each_set_bitfunction ahci_dwc_init_timerfunction ahci_dwc_init_dmacrfunction ahci_dwc_init_hostfunction ahci_dwc_reinit_hostfunction for_each_set_bitfunction ahci_dwc_clear_hostfunction ahci_dwc_stop_hostfunction ahci_dwc_probefunction ahci_dwc_suspendfunction ahci_dwc_resume
Annotated Snippet
struct ahci_dwc_plat_data {
unsigned int pflags;
unsigned int hflags;
int (*init)(struct ahci_host_priv *hpriv);
int (*reinit)(struct ahci_host_priv *hpriv);
void (*clear)(struct ahci_host_priv *hpriv);
};
struct ahci_dwc_host_priv {
const struct ahci_dwc_plat_data *pdata;
struct platform_device *pdev;
u32 timv;
u32 dmacr[AHCI_MAX_PORTS];
};
static struct ahci_host_priv *ahci_dwc_get_resources(struct platform_device *pdev)
{
struct ahci_dwc_host_priv *dpriv;
struct ahci_host_priv *hpriv;
dpriv = devm_kzalloc(&pdev->dev, sizeof(*dpriv), GFP_KERNEL);
if (!dpriv)
return ERR_PTR(-ENOMEM);
dpriv->pdev = pdev;
dpriv->pdata = device_get_match_data(&pdev->dev);
if (!dpriv->pdata)
return ERR_PTR(-EINVAL);
hpriv = ahci_platform_get_resources(pdev, dpriv->pdata->pflags);
if (IS_ERR(hpriv))
return hpriv;
hpriv->flags |= dpriv->pdata->hflags;
hpriv->plat_data = (void *)dpriv;
return hpriv;
}
static void ahci_dwc_check_cap(struct ahci_host_priv *hpriv)
{
unsigned long port_map = hpriv->saved_port_map | hpriv->mask_port_map;
struct ahci_dwc_host_priv *dpriv = hpriv->plat_data;
bool dev_mp, dev_cp, fbs_sup;
unsigned int fbs_pmp;
u32 param;
int i;
param = readl(hpriv->mmio + AHCI_DWC_HOST_GPARAM2R);
dev_mp = !!(param & AHCI_DWC_HOST_DEV_MP);
dev_cp = !!(param & AHCI_DWC_HOST_DEV_CP);
fbs_sup = !!(param & AHCI_DWC_HOST_FBS_SUP);
fbs_pmp = 5 * FIELD_GET(AHCI_DWC_HOST_FBS_PMPN_MASK, param);
if (!dev_mp && hpriv->saved_cap & HOST_CAP_MPS) {
dev_warn(&dpriv->pdev->dev, "MPS is unsupported\n");
hpriv->saved_cap &= ~HOST_CAP_MPS;
}
if (fbs_sup && fbs_pmp < AHCI_DWC_FBS_PMPN_MAX) {
dev_warn(&dpriv->pdev->dev, "PMPn is limited up to %u ports\n",
fbs_pmp);
}
for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {
if (!dev_mp && hpriv->saved_port_cap[i] & PORT_CMD_MPSP) {
dev_warn(&dpriv->pdev->dev, "MPS incapable port %d\n", i);
hpriv->saved_port_cap[i] &= ~PORT_CMD_MPSP;
}
if (!dev_cp && hpriv->saved_port_cap[i] & PORT_CMD_CPD) {
dev_warn(&dpriv->pdev->dev, "CPD incapable port %d\n", i);
hpriv->saved_port_cap[i] &= ~PORT_CMD_CPD;
}
if (!fbs_sup && hpriv->saved_port_cap[i] & PORT_CMD_FBSCP) {
dev_warn(&dpriv->pdev->dev, "FBS incapable port %d\n", i);
hpriv->saved_port_cap[i] &= ~PORT_CMD_FBSCP;
}
}
}
static void ahci_dwc_init_timer(struct ahci_host_priv *hpriv)
{
struct ahci_dwc_host_priv *dpriv = hpriv->plat_data;
unsigned long rate;
struct clk *aclk;
u32 cap, cap2;
Annotation
- Immediate include surface: `linux/ahci_platform.h`, `linux/bitfield.h`, `linux/bits.h`, `linux/clk.h`, `linux/device.h`, `linux/kernel.h`, `linux/libata.h`, `linux/log2.h`.
- Detected declarations: `struct ahci_dwc_plat_data`, `struct ahci_dwc_host_priv`, `function ahci_dwc_check_cap`, `function for_each_set_bit`, `function ahci_dwc_init_timer`, `function ahci_dwc_init_dmacr`, `function ahci_dwc_init_host`, `function ahci_dwc_reinit_host`, `function for_each_set_bit`, `function ahci_dwc_clear_host`.
- Atlas domain: Driver Families / drivers/ata.
- Implementation status: source implementation candidate.
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.