栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux驱动——mmc数据结构(二)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux驱动——mmc数据结构(二)

Linux驱动——mmc数据结构(二)

备注:
  1. Kernel版本:5.4
  2. 使用工具:Source Insight 4.0
  3. 参考博客:
2. [mmc subsystem] mmc core数据结构和宏定义说明
Linux MMC framework(2)_host controller driver

文章目录
  • Linux驱动——mmc数据结构(二)
    • 数据结构关系
    • host 相关
      • struct mmc_host
      • struct mmc_host_ops
    • card相关
      • struct mmc_card
    • host的总线相关
      • struct mmc_bus_ops
      • struct mmc_ios
    • mmc请求相关
      • struct mmc_command
      • struct mmc_data
      • struct mmc_request

数据结构关系

host 相关 struct mmc_host

  struct mmc_host是mmc core由host controller抽象出来的结构体,用于代表一个mmc host控制器。

struct mmc_host {
	struct device		*parent;	//对应的host controller的device
	struct device		class_dev;	// mmc_host的device结构体,会挂在class/mmc_host下
	int			index;				// 该host的索引号
	const struct mmc_host_ops *ops;	// 该host的操作集,由host controller设置
	struct mmc_pwrseq	*pwrseq;	// 该host电源管理有关的操作函数集
	unsigned int		f_min;		// 该host支持的最低频率
	unsigned int		f_max;		// 该host支持的最大频率
	unsigned int		f_init;		// 该host使用的初始化频率

	
	u32			ocr_avail;			// 该host可支持的操作电压范围

	
	u32			ocr_avail_sdio;	
	u32			ocr_avail_sd;	
	u32			ocr_avail_mmc;	
#ifdef CONFIG_PM_SLEEP
	struct notifier_block	pm_notify;// 用于支持power management有关的notify实现
#endif
	u32			max_current_330;	// 3.3V时的最大电流
	u32			max_current_300;	// 3.0V时的最大电流
	u32			max_current_180;	// 1.8V时的最大电流

#define MMC_VDD_165_195		0x00000080	
#define MMC_VDD_20_21		0x00000100	
#define MMC_VDD_21_22		0x00000200	
#define MMC_VDD_22_23		0x00000400	
#define MMC_VDD_23_24		0x00000800	
#define MMC_VDD_24_25		0x00001000	
#define MMC_VDD_25_26		0x00002000	
#define MMC_VDD_26_27		0x00004000	
#define MMC_VDD_27_28		0x00008000	
#define MMC_VDD_28_29		0x00010000	
#define MMC_VDD_29_30		0x00020000	
#define MMC_VDD_30_31		0x00040000	
#define MMC_VDD_31_32		0x00080000	
#define MMC_VDD_32_33		0x00100000	
#define MMC_VDD_33_34		0x00200000	
#define MMC_VDD_34_35		0x00400000	
#define MMC_VDD_35_36		0x00800000	

	// 指示该MMC host所支持的功能特性
	u32			caps;		

#define MMC_CAP_4_BIT_DATA	(1 << 0)	
#define MMC_CAP_MMC_HIGHSPEED	(1 << 1)	
#define MMC_CAP_SD_HIGHSPEED	(1 << 2)	
#define MMC_CAP_SDIO_IRQ	(1 << 3)	
#define MMC_CAP_SPI		(1 << 4)	
#define MMC_CAP_NEEDS_POLL	(1 << 5)	
#define MMC_CAP_8_BIT_DATA	(1 << 6)	
#define MMC_CAP_AGGRESSIVE_PM	(1 << 7)	
#define MMC_CAP_NonREMOVABLE	(1 << 8)	
#define MMC_CAP_WAIT_WHILE_BUSY	(1 << 9)	
#define MMC_CAP_ERASE		(1 << 10)	
#define MMC_CAP_3_3V_DDR	(1 << 11)	
#define MMC_CAP_1_8V_DDR	(1 << 12)	
#define MMC_CAP_1_2V_DDR	(1 << 13)	
#define MMC_CAP_POWER_OFF_CARD	(1 << 14)	
#define MMC_CAP_BUS_WIDTH_TEST	(1 << 15)	
#define MMC_CAP_UHS_SDR12	(1 << 16)	
#define MMC_CAP_UHS_SDR25	(1 << 17)	
#define MMC_CAP_UHS_SDR50	(1 << 18)	
#define MMC_CAP_UHS_SDR104	(1 << 19)	
#define MMC_CAP_UHS_DDR50	(1 << 20)	
#define MMC_CAP_UHS		(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | 
				 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | 
				 MMC_CAP_UHS_DDR50)
#define MMC_CAP_SYNC_RUNTIME_PM	(1 << 21)	
#define MMC_CAP_NEED_RSP_BUSY	(1 << 22)	
#define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	
#define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	
#define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	
#define MMC_CAP_DONE_COMPLETE	(1 << 27)	
#define MMC_CAP_CD_WAKE		(1 << 28)	
#define MMC_CAP_CMD_DURING_TFR	(1 << 29)	
#define MMC_CAP_CMD23		(1 << 30)	
#define MMC_CAP_HW_RESET	(1 << 31)	

	// 指示该MMC host所支持的功能特性
	u32			caps2;		

#define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	
#define MMC_CAP2_FULL_PWR_CYCLE	(1 << 2)	
#define MMC_CAP2_HS200_1_8V_SDR	(1 << 5)        
#define MMC_CAP2_HS200_1_2V_SDR	(1 << 6)        
#define MMC_CAP2_HS200		(MMC_CAP2_HS200_1_8V_SDR | 
				 MMC_CAP2_HS200_1_2V_SDR)
#define MMC_CAP2_CD_ACTIVE_HIGH	(1 << 10)	
#define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	
#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)	
#define MMC_CAP2_HS400_1_8V	(1 << 15)	
#define MMC_CAP2_HS400_1_2V	(1 << 16)	
#define MMC_CAP2_HS400		(MMC_CAP2_HS400_1_8V | 
				 MMC_CAP2_HS400_1_2V)
#define MMC_CAP2_HSX00_1_8V	(MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V)
#define MMC_CAP2_HSX00_1_2V	(MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V)
#define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17)
#define MMC_CAP2_NO_WRITE_PROTECT (1 << 18)	
#define MMC_CAP2_NO_SDIO	(1 << 19)	
#define MMC_CAP2_HS400_ES	(1 << 20)	
#define MMC_CAP2_NO_SD		(1 << 21)	
#define MMC_CAP2_NO_MMC		(1 << 22)	
#define MMC_CAP2_CQE		(1 << 23)	
#define MMC_CAP2_CQE_DCMD	(1 << 24)	
#define MMC_CAP2_AVOID_3_3V	(1 << 25)	
#define MMC_CAP2_MERGE_CAPABLE	(1 << 26)	

	int			fixed_drv_type;	

	// 该host所支持的电源管理特性
	mmc_pm_flag_t		pm_caps;	

	
	unsigned int		max_seg_size;	
	unsigned short		max_segs;	
	unsigned short		unused;
	unsigned int		max_req_size;	
	unsigned int		max_blk_size;	
	unsigned int		max_blk_count;	
	unsigned int		max_busy_timeout; 

	
	// 该host的bus使用的锁
	spinlock_t		lock;		

	// 用于保存MMC bus的当前配置
	struct mmc_ios		ios;		

	
	unsigned int		use_spi_crc:1;
	unsigned int		claimed:1;		// host是否已经被占用
	unsigned int		bus_dead:1;			// host的bus是否处于激活状态
	unsigned int		can_retune:1;	
	unsigned int		doing_retune:1;	
	unsigned int		retune_now:1;	
	unsigned int		retune_paused:1; 
	unsigned int		use_blk_mq:1;	
	unsigned int		retune_crc_disable:1; 
	unsigned int		can_dma_map_merge:1; 

	int			rescan_disable;			// 禁止rescan的标识,禁止搜索card
	int			rescan_entered;	// 是否已经rescan过的标识,对应不可移除的设备只能rescan一次

	int			need_retune;	
	int			hold_retune;	
	unsigned int		retune_period;	
	struct timer_list	retune_timer;	

	bool			trigger_card_event; 

	struct mmc_card		*card;		// 和该host绑定在一起的card

	wait_queue_head_t	wq;
	struct mmc_ctx		*claimer;	// 该host的占有者进程
	int			claim_cnt;	// 占有者进程对该host的占用计数
	struct mmc_ctx		default_ctx;	

	struct delayed_work	detect;	// 检测卡槽变化的工作
	int			detect_change;	// 需要检测卡槽变化的标识
	struct mmc_slot		slot;	// 卡槽的结构体

	const struct mmc_bus_ops *bus_ops;	 // host的mmc总线的操作集
	unsigned int		bus_refs;			 // host的mmc总线的使用计数

	unsigned int		sdio_irqs;
	struct task_struct	*sdio_irq_thread;
	struct delayed_work	sdio_irq_work;
	bool			sdio_irq_pending;
	atomic_t		sdio_irq_thread_abort;

	mmc_pm_flag_t		pm_flags;	

	struct led_trigger	*led;		

#ifdef CONFIG_REGULATOR
	bool			regulator_enabled;  // 代表regulator(LDO)的状态
#endif
	struct mmc_supply	supply;

	struct dentry		*debugfs_root;	// 对应的debug目录结构体

	
	struct mmc_request	*ongoing_mrq;

#ifdef CONFIG_FAIL_MMC_REQUEST
	struct fault_attr	fail_mmc_request;
#endif

	unsigned int		actual_clock;	

	unsigned int		slotno;	

	int			dsr_req;	
	u32			dsr;	

	
	const struct mmc_cqe_ops *cqe_ops;
	void			*cqe_private;
	int			cqe_qdepth;
	bool			cqe_enabled;
	bool			cqe_on;

	unsigned long		private[0] ____cacheline_aligned;
};
struct mmc_host_ops

  mmc core将host需要提供的一些操作方法封装成struct mmc_host_ops。
  mmc core主模块的很多接口都是基于这里面的操作方法来实现的,通过这些方法来操作host硬件达到对应的目的。
  所以struct mmc_host_ops也是host controller driver需要实现的核心部分。

struct mmc_host_ops {
	
	// post_req和pre_req是为了实现异步请求处理而设置的,是非必需的,
	// 异步请求处理就是指,当另外一个异步请求还没有处理完成的时候,
	// 可以先准备另外一个异步请求而不必等待
	void	(*post_req)(struct mmc_host *host, struct mmc_request *req,
			    int err);
	void	(*pre_req)(struct mmc_host *host, struct mmc_request *req);

	// host处理mmc请求的方法,在mmc_start_request中会调用
	void	(*request)(struct mmc_host *host, struct mmc_request *req);

	

	
	// 设置host的总线的io setting
	void	(*set_ios)(struct mmc_host *host, struct mmc_ios *ios);

	
	int	(*get_ro)(struct mmc_host *host); // 获取host上的card的读写属性

	
	int	(*get_cd)(struct mmc_host *host); // 检测host的卡槽中card的插入状态

	void	(*enable_sdio_irq)(struct mmc_host *host, int enable);
	
	void	(*ack_sdio_irq)(struct mmc_host *host);

	 // 初始化card的方法
	void	(*init_card)(struct mmc_host *host, struct mmc_card *card);

	int	(*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);

	
	int	(*card_busy)(struct mmc_host *host); // 用于检测card是否处于busy状态

	
	// 执行tuning操作,为card选择一个合适的采样点
	int	(*execute_tuning)(struct mmc_host *host, u32 opcode);

	
	int	(*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);

	
	int	(*hs400_prepare_ddr)(struct mmc_host *host);

	
	void	(*hs400_downgrade)(struct mmc_host *host);

	
	void	(*hs400_complete)(struct mmc_host *host);

	
	void	(*hs400_enhanced_strobe)(struct mmc_host *host,
					 struct mmc_ios *ios);
	int	(*select_drive_strength)(struct mmc_card *card,
					 unsigned int max_dtr, int host_drv,
					 int card_drv, int *drv_type);
	void	(*hw_reset)(struct mmc_host *host);		// 硬件复位
	void	(*card_event)(struct mmc_host *host);	// 硬件复位

	
	int	(*multi_io_quirk)(struct mmc_card *card,
				  unsigned int direction, int blk_size);
};
card相关 struct mmc_card

  struct mmc_card是mmc core由mmc设备抽象出来的card设备的结构体,用于代表一个mmc设备。

struct mmc_card {
	struct mmc_host		*host;		 // 该mmc_card所属host
	struct device		dev;		 // 对应的device
	u32			ocr;		
	unsigned int		rca;		
	unsigned int		type;		 // card类型
#define MMC_TYPE_MMC		0		
#define MMC_TYPE_SD		1		
#define MMC_TYPE_SDIO		2		
#define MMC_TYPE_SD_COMBO	3		
	unsigned int		state;		 // card的当前状态
	unsigned int		quirks; 	 // 该card的一些特点
	unsigned int		quirk_max_rate;	
#define MMC_QUIRK_LENIENT_FN0	(1<<0)		
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	
						
#define MMC_QUIRK_NONSTD_SDIO	(1<<2)		
						
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4)		
#define MMC_QUIRK_DISABLE_CD	(1<<5)		
#define MMC_QUIRK_INAND_CMD38	(1<<6)		
#define MMC_QUIRK_BLK_NO_CMD23	(1<<7)		
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8)	
						
#define MMC_QUIRK_LONG_READ_TIME (1<<9)		
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)	
#define MMC_QUIRK_BROKEN_IRQ_POLLING	(1<<11)	
#define MMC_QUIRK_TRIM_BROKEN	(1<<12)		
#define MMC_QUIRK_BROKEN_HPI	(1<<13)		

	bool			reenable_cmdq;	

	unsigned int		erase_size;	
 	unsigned int		erase_shift;	
 	unsigned int		pref_erase;	
	unsigned int		eg_boundary;	
	unsigned int		erase_arg;	
 	u8			erased_byte;	

	u32			raw_cid[4];	 // 原始的cid寄存器的值
	u32			raw_csd[4];	 // 原始的csd寄存器的值
	u32			raw_scr[2];	 // 原始的scr寄存器的值
	u32			raw_ssr[16];	 // 原始的ssr寄存器的值
	struct mmc_cid		cid;		 // 从cid寄存器的值解析出来的信息
	struct mmc_csd		csd;		 // 从csd寄存器的值解析出来的信息
	struct mmc_ext_csd	ext_csd;	 // 从ext_csd寄存器的值解析出来的信息
	struct sd_scr		scr;		 // 外部sd card的信息
	struct sd_ssr		ssr;		 // 更多关于sd card的信息
	struct sd_switch_caps	sw_caps;	  // sd的切换属性

	unsigned int		sdio_funcs;	 // sdio funcs的数量
	atomic_t		sdio_funcs_probed; 
	struct sdio_cccr	cccr;		
	struct sdio_cis		cis;		
	struct sdio_func	*sdio_func[SDIO_MAX_FUNCS];  //sdio func指针
	struct sdio_func	*sdio_single_irq; 
	unsigned		num_info;	
	const char		**info;		
	struct sdio_func_tuple	*tuples;	

	unsigned int		sd_bus_speed;	
	unsigned int		mmc_avail_type;	
	unsigned int		drive_strength;	

	struct dentry		*debugfs_root; // 对应debug目录的结构体
	struct mmc_part	part[MMC_NUM_PHY_PARTITION];  // 物理分区
	unsigned int    nr_parts; // 分区数量

	unsigned int		bouncesz;	
	struct workqueue_struct *complete_wq;	
};
host的总线相关 struct mmc_bus_ops

  host的mmc总线的操作集,由host插入的card决定。
  不同类型的card对mmc总线的操作有所不同。

struct mmc_bus_ops {
	void (*remove)(struct mmc_host *); // 从软件上注销mmc总线上的card
	void (*detect)(struct mmc_host *); // 检测mmc总线上的card是否被移除
	int (*pre_suspend)(struct mmc_host *); // suspend前的准备工作
	int (*suspend)(struct mmc_host *); // 对应mmc总线的suspend操作
	int (*resume)(struct mmc_host *);  // 对应mmc总线的resume操作
	int (*runtime_suspend)(struct mmc_host *); // 对应mmc总线的runtime suspend操作
	int (*runtime_resume)(struct mmc_host *);  // 对应mmc总线的runtime resume操作
	int (*alive)(struct mmc_host *);   // 检测mmc总线上的card的激活状态
	int (*shutdown)(struct mmc_host *);// 关闭mmc总线的操作
	int (*hw_reset)(struct mmc_host *);// mmc总线上的HW 复位
	int (*sw_reset)(struct mmc_host *);// mmc总线上的SW 复位
};
struct mmc_ios
struct mmc_ios {
	unsigned int	clock;			 // 当前工作频率
	unsigned short	vdd;			// 支持的电压表
	unsigned int	power_delay_ms;		



	unsigned char	bus_mode;		 // 总线输出模式,包括开漏模式和上拉模式

#define MMC_BUSMODE_OPENDRAIN	1
#define MMC_BUSMODE_PUSHPULL	2

	unsigned char	chip_select;		 // spi片选

#define MMC_CS_DonTCARE		0
#define MMC_CS_HIGH		1
#define MMC_CS_LOW		2

	unsigned char	power_mode;		 // 电源状态模式

#define MMC_POWER_OFF		0
#define MMC_POWER_UP		1
#define MMC_POWER_ON		2
#define MMC_POWER_UNDEFINED	3

	unsigned char	bus_width;		 // 总线宽度

#define MMC_BUS_WIDTH_1		0
#define MMC_BUS_WIDTH_4		2
#define MMC_BUS_WIDTH_8		3

	unsigned char	timing;			 // 时序类型

#define MMC_TIMING_LEGACY	0
#define MMC_TIMING_MMC_HS	1
#define MMC_TIMING_SD_HS	2
#define MMC_TIMING_UHS_SDR12	3
#define MMC_TIMING_UHS_SDR25	4
#define MMC_TIMING_UHS_SDR50	5
#define MMC_TIMING_UHS_SDR104	6
#define MMC_TIMING_UHS_DDR50	7
#define MMC_TIMING_MMC_DDR52	8
#define MMC_TIMING_MMC_HS200	9
#define MMC_TIMING_MMC_HS400	10

	unsigned char	signal_voltage;		 // 信号的工作电压

#define MMC_SIGNAL_VOLTAGE_330	0
#define MMC_SIGNAL_VOLTAGE_180	1
#define MMC_SIGNAL_VOLTAGE_120	2

	unsigned char	drv_type;		 // 驱动类型

#define MMC_SET_DRIVER_TYPE_B	0
#define MMC_SET_DRIVER_TYPE_A	1
#define MMC_SET_DRIVER_TYPE_C	2
#define MMC_SET_DRIVER_TYPE_D	3

	bool enhanced_strobe;			
};
mmc请求相关 struct mmc_command
struct mmc_command {
	u32			opcode; // 命令的操作码,如MMC_GO_IDLE_STATE、MMC_SEND_OP_COND等等
	u32			arg;    // 命令的参数
#define MMC_CMD23_ARG_REL_WR	(1 << 31)
#define MMC_CMD23_ARG_PACKED	((0 << 31) | (1 << 30))
#define MMC_CMD23_ARG_TAG_REQ	(1 << 29)
	u32			resp[4];
	unsigned int		flags;		
#define MMC_RSP_PRESENT	(1 << 0)
#define MMC_RSP_136	(1 << 1)		
#define MMC_RSP_CRC	(1 << 2)		
#define MMC_RSP_BUSY	(1 << 3)		
#define MMC_RSP_OPCODE	(1 << 4)		

#define MMC_CMD_MASK	(3 << 5)		
#define MMC_CMD_AC	(0 << 5)
#define MMC_CMD_ADTC	(1 << 5)
#define MMC_CMD_BC	(2 << 5)
#define MMC_CMD_BCR	(3 << 5)

#define MMC_RSP_SPI_S1	(1 << 7)		
#define MMC_RSP_SPI_S2	(1 << 8)		
#define MMC_RSP_SPI_B4	(1 << 9)		
#define MMC_RSP_SPI_BUSY (1 << 10)		


#define MMC_RSP_NONE	(0)
#define MMC_RSP_R1	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2	(MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3	(MMC_RSP_PRESENT)
#define MMC_RSP_R4	(MMC_RSP_PRESENT)
#define MMC_RSP_R5	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)


#define MMC_RSP_R1_NO_CRC	(MMC_RSP_PRESENT|MMC_RSP_OPCODE)

#define mmc_resp_type(cmd)	((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))


#define MMC_RSP_SPI_R1	(MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B	(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_SPI_R2	(MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R4	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R5	(MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R7	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)

#define mmc_spi_resp_type(cmd)	((cmd)->flags & 
		(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))


#define mmc_cmd_type(cmd)	((cmd)->flags & MMC_CMD_MASK)

	unsigned int		retries;	 // 失败时的重复尝试次数
	int			error;		 // 命令的错误码



	unsigned int		busy_timeout;	
	
	bool			sanitize_busy;

	// 和该命令关联在一起的数据段
	struct mmc_data		*data;		
	// 该命令关联到哪个request
	struct mmc_request	*mrq;		
};
struct mmc_data

mmc core用struct mmc_data来表示一个命令包。

struct mmc_data {
	unsigned int		timeout_ns;	 // 超时时间,以ns为单位
	unsigned int		timeout_clks;	   // 超时时间,以clock为单位
	unsigned int		blksz;		  // 块大小
	unsigned int		blocks;		 // 块数量
	unsigned int		blk_addr;	    // card地址
	int			error;		
	unsigned int		flags;      // 传输标识

#define MMC_DATA_WRITE		BIT(8)
#define MMC_DATA_READ		BIT(9)

#define MMC_DATA_QBR		BIT(10)		
#define MMC_DATA_PRIO		BIT(11)		
#define MMC_DATA_REL_WR		BIT(12)		
#define MMC_DATA_DAT_TAG	BIT(13)		
#define MMC_DATA_FORCED_PRG	BIT(14)		

	unsigned int		bytes_xfered;

	struct mmc_command	*stop;		  	// 结束传输的命令
	struct mmc_request	*mrq;		// 该命令关联到哪个request

	unsigned int		sg_len;		 sg数组的size
	int			sg_count;	 // 通过sg map出来的实际的entry的个
	struct scatterlist	*sg;		 //一个struct scatterlist类型的数组
	s32			host_cookie;	 // host driver的私有数据
};
struct mmc_request

  struct mmc_request是mmc core向host controller发起命令请求的处理单位。其包含了要传输的命令和数据。

struct mmc_request {
	struct mmc_command	*sbc;		 // 设置块数量的命令,怎么用的后续再补充
	struct mmc_command	*cmd;		// 要传输的命令
	struct mmc_data		*data;		// 要传输的数据
	struct mmc_command	*stop;		// 要传输的stop命令

	struct completion	completion; // 完成量
	struct completion	cmd_completion;

	// 传输结束后的回调函数
	void			(*done)(struct mmc_request *);
	
	void			(*recovery_notifier)(struct mmc_request *);
	struct mmc_host		*host; // 所属host

	
	bool			cap_cmd_during_tfr;

	int			tag;
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/341742.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号