drivers/mmc/host/cqhci-core.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/cqhci-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/cqhci-core.c- Extension
.c- Size
- 31125 bytes
- Lines
- 1233
- Domain
- Driver Families
- Bucket
- drivers/mmc
- 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/delay.hlinux/highmem.hlinux/io.hlinux/iopoll.hlinux/module.hlinux/dma-mapping.hlinux/slab.hlinux/scatterlist.hlinux/platform_device.hlinux/ktime.hlinux/mmc/mmc.hlinux/mmc/host.hlinux/mmc/card.hcqhci.hcqhci-crypto.h
Detected Declarations
struct cqhci_slotfunction cqhci_haltedfunction get_trans_desc_offsetfunction get_trans_desc_dmafunction setup_trans_descfunction cqhci_set_irqsfunction cqhci_dumpregsfunction cqhci_host_alloc_tdlfunction __cqhci_enablefunction __cqhci_disablefunction cqhci_deactivatefunction cqhci_resumefunction cqhci_enablefunction cqhci_read_ctlfunction cqhci_offfunction cqhci_disablefunction cqhci_prep_task_descfunction cqhci_dma_mapfunction cqhci_set_tran_descfunction cqhci_prep_tran_descfunction for_each_sgfunction cqhci_prep_dcmd_descfunction cqhci_post_reqfunction cqhci_tagfunction cqhci_requestfunction cqhci_recovery_neededfunction cqhci_error_flagsfunction cqhci_error_irqfunction cqhci_finish_mrqfunction cqhci_irqfunction for_each_set_bitfunction cqhci_is_idlefunction cqhci_wait_for_idlefunction cqhci_timeoutfunction cqhci_tasks_clearedfunction cqhci_clear_all_tasksfunction cqhci_haltfunction usefunction cqhci_error_from_flagsfunction cqhci_recover_mrqfunction cqhci_recover_mrqsfunction cqhci_recovery_finishfunction cqhci_ver_majorfunction cqhci_ver_minorfunction cqhci_initexport cqhci_deactivateexport cqhci_resumeexport cqhci_set_tran_desc
Annotated Snippet
struct cqhci_slot {
struct mmc_request *mrq;
unsigned int flags;
#define CQHCI_EXTERNAL_TIMEOUT BIT(0)
#define CQHCI_COMPLETED BIT(1)
#define CQHCI_HOST_CRC BIT(2)
#define CQHCI_HOST_TIMEOUT BIT(3)
#define CQHCI_HOST_OTHER BIT(4)
};
static bool cqhci_halted(struct cqhci_host *cq_host)
{
return cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT;
}
static inline u8 *get_desc(struct cqhci_host *cq_host, u8 tag)
{
return cq_host->desc_base + (tag * cq_host->slot_sz);
}
static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag)
{
u8 *desc = get_desc(cq_host, tag);
return desc + cq_host->task_desc_len;
}
static inline size_t get_trans_desc_offset(struct cqhci_host *cq_host, u8 tag)
{
return cq_host->trans_desc_len * cq_host->mmc->max_segs * tag;
}
static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)
{
size_t offset = get_trans_desc_offset(cq_host, tag);
return cq_host->trans_desc_dma_base + offset;
}
static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag)
{
size_t offset = get_trans_desc_offset(cq_host, tag);
return cq_host->trans_desc_base + offset;
}
static void setup_trans_desc(struct cqhci_host *cq_host, u8 tag)
{
u8 *link_temp;
dma_addr_t trans_temp;
link_temp = get_link_desc(cq_host, tag);
trans_temp = get_trans_desc_dma(cq_host, tag);
memset(link_temp, 0, cq_host->link_desc_len);
if (cq_host->link_desc_len > 8)
*(link_temp + 8) = 0;
if (tag == DCMD_SLOT && (cq_host->mmc->caps2 & MMC_CAP2_CQE_DCMD)) {
*link_temp = CQHCI_VALID(0) | CQHCI_ACT(0) | CQHCI_END(1);
return;
}
*link_temp = CQHCI_VALID(1) | CQHCI_ACT(0x6) | CQHCI_END(0);
if (cq_host->dma64) {
__le64 *data_addr = (__le64 __force *)(link_temp + 4);
data_addr[0] = cpu_to_le64(trans_temp);
} else {
__le32 *data_addr = (__le32 __force *)(link_temp + 4);
data_addr[0] = cpu_to_le32(trans_temp);
}
}
static void cqhci_set_irqs(struct cqhci_host *cq_host, u32 set)
{
cqhci_writel(cq_host, set, CQHCI_ISTE);
cqhci_writel(cq_host, set, CQHCI_ISGE);
}
#define DRV_NAME "cqhci"
#define CQHCI_DUMP(f, x...) \
pr_err("%s: " DRV_NAME ": " f, mmc_hostname(mmc), ## x)
static void cqhci_dumpregs(struct cqhci_host *cq_host)
{
struct mmc_host *mmc = cq_host->mmc;
Annotation
- Immediate include surface: `linux/delay.h`, `linux/highmem.h`, `linux/io.h`, `linux/iopoll.h`, `linux/module.h`, `linux/dma-mapping.h`, `linux/slab.h`, `linux/scatterlist.h`.
- Detected declarations: `struct cqhci_slot`, `function cqhci_halted`, `function get_trans_desc_offset`, `function get_trans_desc_dma`, `function setup_trans_desc`, `function cqhci_set_irqs`, `function cqhci_dumpregs`, `function cqhci_host_alloc_tdl`, `function __cqhci_enable`, `function __cqhci_disable`.
- Atlas domain: Driver Families / drivers/mmc.
- 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.