Linux驱动——mmc sd card 块设备读写流程(十三)

本文详细介绍了Linux内核5.4版本中,mmc/sdcard块设备的读写流程,涉及mmc_mq_ops结构体解析、mmc_mq_init_request、mmc_mq_exit_request等关键函数的实现。通过源码分析,揭示了从blk_mq_queue_rq到mmc_blk_mq_issue_rq的数据收发过程,并展示了读写操作的调用栈,对于理解Linux MMC驱动的工作原理具有指导意义。

Linux驱动——mmc sd card 块设备读写流程(十三)

备注:
  1. Kernel版本:5.4
  2. 使用工具:Source Insight 4.0
  3. 参考博客:
  (1)[sd card] sd card块设备(mmc_blk)读写流程学习笔记

MMC blk_mq_ops的实现

blk_mq_ops结构体成员解析

//源码:include/linux/blk-mq.h
typedef blk_status_t (queue_rq_fn)(struct blk_mq_hw_ctx *,
		const struct blk_mq_queue_data *);
typedef void (commit_rqs_fn)(struct blk_mq_hw_ctx *);
typedef bool (get_budget_fn)(struct blk_mq_hw_ctx *);
typedef void (put_budget_fn)(struct blk_mq_hw_ctx *);
typedef enum blk_eh_timer_return (timeout_fn)(struct request *, bool);
typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);
typedef void (exit_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
typedef int (init_request_fn)(struct blk_mq_tag_set *set, struct request *,
		unsigned int, unsigned int);
typedef void (exit_request_fn)(struct blk_mq_tag_set *set, struct request *,
		unsigned int);

typedef bool (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *,
		bool);
typedef bool (busy_tag_iter_fn)(struct request *, void *, bool);
typedef int (poll_fn)(struct blk_mq_hw_ctx *);
typedef int (map_queues_fn)(struct blk_mq_tag_set *set);
typedef bool (busy_fn)(struct request_queue *);
typedef void (complete_fn)(struct request *);
typedef void (cleanup_rq_fn)(struct request *);


struct blk_mq_ops {
	/*
	 * Queue request
	 */
	queue_rq_fn		*queue_rq;//对来自块 IO 的新请求进行排队

	/*
	 * If a driver uses bd->last to judge when to submit requests to
	 * hardware, it must define this function. In case of errors that
	 * make us stop issuing further requests, this hook serves the
	 * purpose of kicking the hardware (which the last request otherwise
	 * would have done).
	 */
	// 如果驱动使用 bd->last 判断何时向硬件提交请求,则必须定义该函数。
	// 如果出现使我们停止发出进一步请求的错误,
	// 这个钩子的目的是踢掉硬件(否则最后一个请求会这样做)。
	commit_rqs_fn		*commit_rqs;

	/*
	 * Reserve budget before queue request, once .queue_rq is
	 * run, it is driver's responsibility to release the
	 * reserved budget. Also we have to handle failure case
	 * of .get_budget for avoiding I/O deadlock.
	 */
	// 在队列请求之前预留预算,一旦 .queue_rq 运行,驱动程序有责任释放预留的预算。
	// 我们还必须处理 .get_budget 的失败情况以避免 I/O 死锁。
	get_budget_fn		*get_budget;

	// 释放预留的预算
	put_budget_fn		*put_budget;

	/*
	 * Called on request timeout
	 */
	// 在请求超时时调用
	timeout_fn		*timeout;

	/*
	 * Called to poll for completion of a specific tag.
	 */
	// 调用以轮询特定标记的完成情况
	poll_fn			*poll;

	// 将请求标记为完成
	complete_fn		*complete;

	/*
	 * Called when the block layer side of a hardware queue has been
	 * set up, allowing the driver to allocate/init matching structures.
	 * Ditto for
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值