drivers/ufs/core/ufs-mcq.c
Source file repositories/reference/linux-study-clean/drivers/ufs/core/ufs-mcq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ufs/core/ufs-mcq.c- Extension
.c- Size
- 20548 bytes
- Lines
- 738
- Domain
- Driver Families
- Bucket
- drivers/ufs
- 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.
- 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/unaligned.hlinux/dma-mapping.hlinux/module.hlinux/platform_device.hufshcd-priv.hlinux/delay.hscsi/scsi_cmnd.hlinux/bitfield.hlinux/iopoll.h
Detected Declarations
function Copyrightfunction read_queue_count_setfunction poll_queue_count_setfunction ufshcd_mcq_config_macfunction ufshcd_mcq_queue_cfg_addrfunction ufshcd_get_hba_macfunction ufshcd_mcq_config_nr_queuesfunction ufshcd_mcq_memory_allocfunction ufshcd_mcq_read_cqisfunction ufshcd_mcq_write_cqisfunction ufshcd_mcq_read_mcqiacrfunction ufshcd_mcq_write_mcqiacrfunction ufshcd_mcq_get_tagfunction ufshcd_mcq_process_cqefunction disabledfunction ufshcd_mcq_poll_cqe_lockfunction ufshcd_mcq_make_queues_operationalfunction ufshcd_mcq_enablefunction ufshcd_mcq_disablefunction ufshcd_mcq_enable_esifunction ufshcd_mcq_config_esifunction ufshcd_mcq_initfunction ufshcd_mcq_sq_stopfunction ufshcd_mcq_sq_startfunction ufshcd_mcq_sq_cleanupfunction ufshcd_mcq_nullify_sqefunction ufshcd_mcq_sqe_searchfunction ufshcd_mcq_abortexport ufshcd_mcq_config_macexport ufshcd_mcq_queue_cfg_addrexport ufshcd_mcq_read_cqisexport ufshcd_mcq_write_cqisexport ufshcd_mcq_poll_cqe_lockexport ufshcd_mcq_make_queues_operationalexport ufshcd_mcq_enableexport ufshcd_mcq_enable_esiexport ufshcd_mcq_config_esi
Annotated Snippet
if (!hwq->sqe_base_addr) {
dev_err(hba->dev, "SQE allocation failed\n");
return -ENOMEM;
}
cqe_size = sizeof(struct cq_entry) * hwq->max_entries;
hwq->cqe_base_addr = dmam_alloc_coherent(hba->dev, cqe_size,
&hwq->cqe_dma_addr,
GFP_KERNEL);
if (!hwq->cqe_base_addr) {
dev_err(hba->dev, "CQE allocation failed\n");
return -ENOMEM;
}
}
return 0;
}
static void __iomem *mcq_opr_base(struct ufs_hba *hba,
enum ufshcd_mcq_opr n, int i)
{
struct ufshcd_mcq_opr_info_t *opr = &hba->mcq_opr[n];
return opr->base + opr->stride * i;
}
u32 ufshcd_mcq_read_cqis(struct ufs_hba *hba, int i)
{
return readl(mcq_opr_base(hba, OPR_CQIS, i) + REG_CQIS);
}
EXPORT_SYMBOL_GPL(ufshcd_mcq_read_cqis);
void ufshcd_mcq_write_cqis(struct ufs_hba *hba, u32 val, int i)
{
writel(val, mcq_opr_base(hba, OPR_CQIS, i) + REG_CQIS);
}
EXPORT_SYMBOL_GPL(ufshcd_mcq_write_cqis);
u32 ufshcd_mcq_read_mcqiacr(struct ufs_hba *hba, int i)
{
return readl(mcq_opr_base(hba, OPR_CQIS, i) + REG_MCQIACR);
}
void ufshcd_mcq_write_mcqiacr(struct ufs_hba *hba, u32 val, int i)
{
writel(val, mcq_opr_base(hba, OPR_CQIS, i) + REG_MCQIACR);
}
/*
* UFSHCI 4.0 MCQ specification doesn't provide a Task Tag or its equivalent in
* the Completion Queue Entry. Find the Task Tag using an indirect method.
* UFSHCI 4.1 and above can directly return the Task Tag in the Completion Queue
* Entry.
*/
static int ufshcd_mcq_get_tag(struct ufs_hba *hba, struct cq_entry *cqe)
{
u64 addr;
if (hba->ufs_version >= ufshci_version(4, 1))
return cqe->task_tag;
/* sizeof(struct utp_transfer_cmd_desc) must be a multiple of 128 */
BUILD_BUG_ON(sizeof(struct utp_transfer_cmd_desc) & GENMASK(6, 0));
/* Bits 63:7 UCD base address, 6:5 are reserved, 4:0 is SQ ID */
addr = (le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA) -
hba->ucdl_dma_addr;
return div_u64(addr, ufshcd_get_ucd_size(hba));
}
static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,
struct ufs_hw_queue *hwq)
{
struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq);
if (cqe->command_desc_base_addr) {
int tag = ufshcd_mcq_get_tag(hba, cqe);
ufshcd_compl_one_cqe(hba, tag, cqe);
/* After processed the cqe, mark it empty (invalid) entry */
cqe->command_desc_base_addr = 0;
} else {
dev_err(hba->dev, "Abnormal CQ entry!\n");
}
}
/*
* This function is called from the UFS error handler with the UFS host
* controller disabled (HCE = 0). Reading host controller registers, e.g. the
Annotation
- Immediate include surface: `linux/unaligned.h`, `linux/dma-mapping.h`, `linux/module.h`, `linux/platform_device.h`, `ufshcd-priv.h`, `linux/delay.h`, `scsi/scsi_cmnd.h`, `linux/bitfield.h`.
- Detected declarations: `function Copyright`, `function read_queue_count_set`, `function poll_queue_count_set`, `function ufshcd_mcq_config_mac`, `function ufshcd_mcq_queue_cfg_addr`, `function ufshcd_get_hba_mac`, `function ufshcd_mcq_config_nr_queues`, `function ufshcd_mcq_memory_alloc`, `function ufshcd_mcq_read_cqis`, `function ufshcd_mcq_write_cqis`.
- Atlas domain: Driver Families / drivers/ufs.
- Implementation status: integration 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.