2. [mmc subsystem] mmc core数据结构和宏定义说明
一、host相关
1、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设置,后面说明
unsigned int f_min; // 该host支持的最低频率
unsigned int f_max; // 该host支持的最大频率
unsigned int f_init; // 该host使用的初始化频率
u32 ocr_avail; // 该host可用的ocr值(电压相关)
u32 ocr_avail_sdio; /* SDIO-specific OCR */
u32 ocr_avail_sd; /* SD-specific OCR */
u32 ocr_avail_mmc; /* MMC-specific OCR */
struct notifier_block pm_notify;
u32 max_current_330; // 3.3V时的最大电流
u32 max_current_300; // 3.0V时的最大电流
u32 max_current_180; // 1.8V时的最大电流
u32 caps; /* Host capabilities */ // host属性
u32 caps2; /* More host capabilities */ // host属性2
mmc_pm_flag_t pm_caps; /* supported pm features */ // 电源管理属性
/////////////////////////////////////////////////////// 以下是和clock相关的成员
int clk_requests; /* internal reference counter */
unsigned int clk_delay; /* number of MCI clk hold cycles */
bool clk_gated; /* clock gated */
struct delayed_work clk_gate_work; /* delayed clock gate */
unsigned int clk_old; /* old clock value cache */
spinlock_t clk_lock; /* lock for clk fields */
struct mutex clk_gate_mutex; /* mutex for clock gating */
struct device_attribute clkgate_delay_attr;
unsigned long clkgate_delay;
/* host specific block data */
////////////////////////////////////////////////////// 和块相关的成员
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
unsigned short max_segs; /* see blk_queue_max_segments */
unsigned short unused;
unsigned int max_req_size; /* maximum number of bytes in one req */
unsigned int max_blk_size; /* maximum size of one mmc block */
unsigned int max_blk_count; /* maximum number of blocks in one req */
unsigned int max_discard_to; /* max. discard timeout in ms */
/* private data */
spinlock_t lock; /* lock for claim and bus ops */ // host的bus使用的锁
struct mmc_ios ios; /* current io bus settings */ // io setting,后续说明
u32 ocr; /* the current OCR setting */ // 当前使用的ocr的值
/* group bitfields together to minimize padding */
unsigned int use_spi_crc:1;
unsigned int claimed:1; /* host exclusively claimed */ // host是否已经被占用
unsigned int bus_dead:1; /* bus has been released */ // host的bus是否处于激活状态
int rescan_disable; /* disable card detection */ // 禁止rescan的标识,禁止搜索card
int rescan_entered; /* used with nonremovable devices */ // 是否已经rescan过的标识,对应不可移除的设备只能rescan一次
struct mmc_card *card; /* device attached to this host */ // 和该host绑定在一起的card
wait_queue_head_t wq;
struct task_struct *claimer; /* task that has host claimed */ // 该host的占有者进程
struct task_struct *suspend_task;
int claim_cnt; /* "claim" nesting count */ // 占有者进程对该host的占用计数
struct delayed_work detect; // 检测卡槽变化的工作
struct wake_lock detect_wake_lock; // 检测卡槽变化的工作使用的锁
const char *wlock_name; // 锁名称
int detect_change; /* card detect flag */ // 需要检测卡槽变化的标识
struct mmc_slot slot; // 卡槽的结构体
const struct mmc_bus_ops *bus_ops; /* current bus driver */ // host的mmc总线的操作集,后面说明
unsigned int bus_refs; /* reference counter */ // host的mmc总线的使用计数
unsigned int bus_resume_flags; // host的mmc总线的resume标识
mmc_pm_flag_t pm_flags; /* requested pm features */
#ifdef CONFIG_REGULATOR
bool regulator_enabled; /* regulator state */ // 代表regulator(LDO)的状态
#endif
struct mmc_supply supply;
struct dentry *debugfs_root; // 对应的debug目录结构体
struct mmc_async_req *areq; /* active async req */ // 当前正在处理的异步请求
struct mmc_context_info context_info; /* async synchronization info */ // 异步请求的信息
unsigned int actual_clock; /* Actual HC clock rate */ // 实际的时钟频率
};
ocr值各个位代表的电压意义如下:
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
host属性2(mmc_host->caps2)支持的属性如下
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
#define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */
#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
#define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */
#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
MMC_CAP2_HS200_1_2V_SDR)
#define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */
#define MMC_CAP2_DETECT_ON_ERR (1 << 8) /* On I/O err check card removal */
#define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */
#define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
#define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */
#define MMC_CAP2_PACKED_RD (1 << 12) /* Allow packed read */
#define MMC_CAP2_PACKED_WR (1 << 13) /* Allow packed write */
#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \
MMC_CAP2_PACKED_WR)
#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
#define MMC_CAP2_INIT_BKOPS (1 << 15) /* Need to set BKOPS_EN */
#define MMC_CAP2_PACKED_WR_CONTROL (1 << 16) /* Allow write packing control */
#define MMC_CAP2_CLK_SCALE (1 << 17) /* Allow dynamic clk scaling */
#define MMC_CAP2_STOP_REQUEST (1 << 18) /* Allow stop ongoing request */
/* Use runtime PM framework provided by MMC core */
#define MMC_CAP2_CORE_RUNTIME_PM (1 << 19)
#define MMC_CAP2_SANITIZE (1 << 20) /* Support Sanitize */
/* Allows Asynchronous SDIO irq while card is in 4-bit mode */
#define MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE (1 << 21)
#define MMC_CAP2_HS400_1_8V (1 << 22) /* can support */
#define MMC_CAP2_HS400_1_2V (1 << 23) /* can support */
#define MMC_CAP2_CORE_PM (1 << 24) /* use PM framework */
#define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \
MMC_CAP2_HS400_1_2V)
#define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/
2、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 {
/*
* 'enable' is called when the host is claimed and 'disable' is called
* when the host is released. 'enable' and 'disable' are deprecated.
*/
int (*enable)(struct mmc_host *host); // 使能host,当host被占用时(第一次调用mmc_claim_host)调用
int (*disable)(struct mmc_host *host); // 禁用host,当host被释放时(第一次调用mmc_release_host)调用
/*
* It is optional for the host to implement pre_req and post_req in
* order to support double buffering of requests (prepare one
* request while another request is active).
* pre_req() must always be followed by a post_req().
* To undo a call made to pre_req(), call post_req() with
* a nonzero err condition.
*/
// post_req和pre_req是为了实现异步请求处理而设置的
// 异步请求处理就是指,当另外一个异步请求还没有处理完成的时候,可以先准备另外一个异步请求而不必等待
// 具体参考《mmc core主模块》
void (*post_req)(struct mmc_host *host, struct mmc_request *req,
int err);
void (*pre_req)(struct mmc_host *host, struct mmc_request *req,
bool is_first_req);
void (*request)(struct mmc_host *host, struct mmc_request *req); // host处理mmc请求的方法,在mmc_start_request中会调用
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); // 设置host的总线的io setting
int (*get_ro)(struct mmc_host *host); // 获取host上的card的读写属性
int (*get_cd)(struct mmc_host *host); // 检测host的卡槽中card的插入状态
/* optional callback for HC quirks */
void (*init_card)(struct mmc_host *host, struct mmc_card *card); // 初始化card的方法
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); // 切换信号电压的方法
/* Check if the card is pulling dat[0:3] low */
int (*card_busy)(struct mmc_host *host); // 用于检测card是否处于busy状态
/* The tuning command opcode value is different for SD and eMMC cards */
int (*execute_tuning)(struct mmc_host *host, u32 opcode); // 执行tuning操作,为card选择一个合适的采样点
int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); // 选择信号的驱动强度
void (*hw_reset)(struct mmc_host *host); // 硬件复位
void (*card_event)(struct mmc_host *host); //
unsigned long (*get_max_frequency)(struct mmc_host *host); // 获取host支持的最大频率的方法
unsigned long (*get_min_frequency)(struct mmc_host *host); // 获取host支持的最小频率的方法
int (*notify_load)(struct mmc_host *, enum mmc_load);
int (*stop_request)(struct mmc_host *host); // 停止请求处理的方法
unsigned int (*get_xfer_remain)(struct mmc_host *host);
};
二、card相关
1、struct mmc_card
struct mmc_card是mmc core由mmc设备抽象出来的card设备的结构体,用于代表一个mmc设备。
数据结构如下:
struct mmc_card {
struct mmc_host *host; /* the host this device belongs to */ // 该mmc_card所属host
struct device dev; /* the device */ // 对应的device
unsigned int rca; /* relative card address of device */ // 该card的RCA地址
unsigned int type; /* card type */ // card类型,后面说明
unsigned int state; /* (our) card state */ // card的当前状态,后面说明
unsigned int quirks; /* card quirks */ // 该card的一些特点
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
unsigned int pref_erase; /* in sectors */
u8 erased_byte; /* value of erased bytes */
u32 raw_cid[4]; /* raw card CID */ // 原始的cid寄存器的值
u32 raw_csd[4]; /* raw card CSD */ // 原始的csd寄存器的值
u32 raw_scr[2]; /* raw card SCR */ // 原始的scr寄存器的值
struct mmc_cid cid; /* card identification */ // 从cid寄存器的值解析出来的信息
struct mmc_csd csd; /* card specific */ // 从csd寄存器的值解析出来的信息
struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ // 从ext_csd寄存器的值解析出来的信息
struct sd_scr scr; /* extra SD information */ // 外部sdcard的信息
struct sd_ssr ssr; /* yet more SD information */ // 更多关于sd card的信息
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ // sd的切换属性
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */
struct dentry *debugfs_root; // 对应debug目录的结构体
struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ // 物理分区
unsigned int nr_parts; // 分区数量
unsigned int part_curr; // 当前分区
struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/
struct mmc_bkops_info bkops_info;
struct device_attribute rpm_attrib; // rpm属性
unsigned int idle_timeout;
struct notifier_block reboot_notify;
bool issue_long_pon;
u8 *cached_ext_csd;
};
- mmc card类型(mmc_card->type)如下:
#define MMC_TYPE_MMC 0 /* MMC card */
#define MMC_TYPE_SD 1 /* SD card */
#define MMC_TYPE_SDIO 2 /* SDIO card */
#define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */
- mmc card状态(mmc_card->state)如下:
#define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
#define MMC_STATE_READONLY (1<<1) /* card is read-only */
#define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */
#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
#define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
#define MMC_STATE_HIGHSPEED_400 (1<<9) /* card is in HS400 mode */
#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
#define MMC_STATE_NEED_BKOPS (1<<11) /* card needs to do BKOPS */
- mmc card的一些特写标识(mmc_card->quirks)如下:
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
/* for byte mode */
#define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */
/* (missing CIA registers) */
#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
/* byte mode */
#define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<11) /* For incorrect data timeout */
/* To avoid eMMC device getting broken permanently due to HPI feature */
#define MMC_QUIRK_BROKEN_HPI (1 << 12)
/* Skip data-timeout advertised by card */
#define MMC_QUIRK_BROKEN_DATA_TIMEOUT (1<<13)
#define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */
三、host的总线相关
1、struct mmc_bus_ops
host的mmc总线的操作集,由host插入的card决定。
不同类型的card对mmc总线的操作有所不同。
结构体如下:
struct mmc_bus_ops {
int (*awake)(struct mmc_host *); // 唤醒mmc总线上的card
int (*sleep)(struct mmc_host *); // 休眠mmc总线上的card
void (*remove)(struct mmc_host *); // 从软件上注销mmc总线上的card
void (*detect)(struct mmc_host *); // 检测mmc总线上的card是否被移除
int (*suspend)(struct mmc_host *); // 对应mmc总线的suspend操作
int (*resume)(struct mmc_host *); // 对应mmc总线的resume操作
int (*power_save)(struct mmc_host *); // 存储电源状态
int (*power_restore)(struct mmc_host *); // 恢复电源状态
int (*alive)(struct mmc_host *); // 检测mmc总线上的card的激活状态
int (*change_bus_speed)(struct mmc_host *, unsigned long *); // 修改mmc总线的工作时钟
};
2、struct mmc_ios
struct mmc_ios 由mmc core定义的规范的结构,用来维护mmc总线相关的一些io setting。如下:
struct mmc_ios {
unsigned int clock; /* clock rate */ // 当前工作频率
unsigned int old_rate; /* saved clock rate */ // 上一次的工作频率
unsigned long clk_ts; /* time stamp of last updated clock */ // 上一次更新工作频率的时间戳
unsigned short vdd;/* vdd stores the bit number of the selected voltage range from below. */ // 支持的电压表
unsigned char bus_mode; /* command output mode */ // 总线输出模式,包括开漏模式和上拉模式
unsigned char chip_select; /* SPI chip select */ // spi片选
unsigned char power_mode; /* power supply mode */ // 电源状态模式
unsigned char bus_width; /* data bus width */ // 总线宽度
unsigned char timing; /* timing specification used */ // 时序类型
unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ // 信号的工作电压
unsigned char drv_type; /* driver type (A, B, C, D) */ // 驱动类型
};
四、请求相关
1、struct mmc_command
数据结构如下:
struct mmc_command {
u32 opcode; // 命令的操作码,如MMC_GO_IDLE_STATE、MMC_SEND_OP_COND等等
u32 arg; // 命令的参数
u32 resp[4]; // response值
unsigned int flags; /* expected response type */ // 期待的response的类型,具体参考后面的命令类型和response类型
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
unsigned int retries; /* max number of retries */ // 失败时的重复尝试次数
unsigned int error; /* command error */ // 命令的错误码
unsigned int cmd_timeout_ms; /* in milliseconds */ // 命令执行的等待超时事件
struct mmc_data *data; /* data segment associated with cmd */ // 和该命令关联在一起的数据段
struct mmc_request *mrq; /* associated request */ // 该命令关联到哪个request
};
命令类型如下(和协议相关):
#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
response类型如下(和协议相关):
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#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)
2、struct mmc_data
mmc core用struct mmc_data来表示一个命令包
struct mmc_data {
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ // 超时时间,以ns为单位
unsigned int timeout_clks; /* data timeout (in clocks) */ // 超时时间,以clock为单位
unsigned int blksz; /* data block size */ // 块大小
unsigned int blocks; /* number of blocks */ // 块数量
unsigned int error; /* data error */ // 传输的错误码
unsigned int flags; // 传输标识
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */ // 结束传输的命令
struct mmc_request *mrq; /* associated request */ // 该命令关联到哪个request
unsigned int sg_len; /* size of scatter list */
struct scatterlist *sg; /* I/O scatter list */
s32 host_cookie; /* host private data */
bool fault_injected; /* fault injected */
};
3、struct mmc_request
struct mmc_request是mmc core向host controller发起命令请求的处理单位。
其包含了要传输的命令和数据。
struct mmc_request {
struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */ // 设置块数量的命令,怎么用的后续再补充
struct mmc_command *cmd; // 要传输的命令
struct mmc_data *data; // 要传输的数据
struct mmc_command *stop; // 结束命令,怎么用的后续再补充
struct completion completion; // 完成量
void (*done)(struct mmc_request *);/* completion function */ // 传输结束后的回调函数
struct mmc_host *host; // 所属host
};
4、struct mmc_async_req
异步请求的结构体。封装了struct mmc_request请求结构体。具体参考《mmc core主模块说明》
struct mmc_async_req {
/* active mmc request */
struct mmc_request *mrq; // mmc请求
unsigned int cmd_flags; /* copied from struct request */ // 命令标识
/*
* Check error status of completed mmc request.
* Returns 0 if success otherwise non zero.
*/
int (*err_check) (struct mmc_card *, struct mmc_async_req *);
/* Reinserts request back to the block layer */
void (*reinsert_req) (struct mmc_async_req *);
/* update what part of request is not done (packed_fail_idx) */
int (*update_interrupted_req) (struct mmc_card *,
struct mmc_async_req *);
};
2. [mmc subsystem] mmc core数据结构和宏定义说明的更多相关文章
- 5. [mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)
零.说明(重要,需要先搞清楚概念有助于后面的理解) 1.mmc core card相关模块为对应card实现相应的操作,包括初始化操作.以及对应的总线操作集合.负责和对应card协议层相关的东西. 这 ...
- 4. [mmc subsystem] mmc core(第四章)——host模块说明
零.说明 对应代码drivers/mmc/core/host.c,drivers/mmc/core/host.h. 为底层host controller driver实现mmc host的申请以及注册 ...
- 3. [mmc subsystem] mmc core(第三章)——bus模块说明
零.说明 对应代码drivers/mmc/core/bus.c. 抽象出虚拟mmc bus,实现mmc bus的操作. 一.API总览 1.mmc bus相关 mmc_register_bus &am ...
- 6. [mmc subsystem] mmc core(第六章)——mmc core主模块
一.说明 1.mmc core概述 mmc core主模块是mmc core的实现核心.也是本章的重点内容. 对应代码位置drivers/mmc/core/core.c. 其主要负责如下功能: mmc ...
- 8. [mmc subsystem] host(第二章)——sdhci
一.sdhci core说明 1.sdhci说明 具体参考<host(第一章)--概述> SDHC:Secure Digital(SD) Host Controller,是指一套sd ho ...
- 1. [mmc subsystem] 概念与框架
一.概念 1.mmc的概念 mmc有很多种意义,具体如下: mmc MultiMedia Card,多媒体存储卡, 但后续泛指一个接口协定(一种卡式),能符合这接口的内存器都可称作mmc储存体. 主要 ...
- 10. [mmc subsystem] host(第四章)——host实例(sdhci-msm说明)
一.说明 sdhci-msm是指高通的mmc host,其使用了标准SDHC标准.故可以使用前面说的<host(第二章)--sdhci>和<host(第三章)--sdhci-pltf ...
- 7. [mmc subsystem] host(第一章)——概述
一.host简单说明 host,也可以理解为host controller,是指mmc总线上的主机端,mmc总线的控制器,每个host controller对应一条mmc总线. host contro ...
- .NET Core 数据结构与算法 1-1
.NET Core 数据结构与算法 1-1 本节内容为顺序表 简介 线性表是简单.基本.常用的数据结构.线性表是线性结构的抽象 (Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线 ...
随机推荐
- LR测试
LoadRunner种预测系统行性能负载测试工具通模拟千万用户实施并发负载及实性能监测式确认查找问题LoadRunner能够整企业架构进行测试通使用 LoadRunner企业能限度缩短测试间优化性能加 ...
- 页面读取Excel
var input = document.getElementById("file"); //支持chrome IE10 if (window.FileReader) ...
- 定时器Timer的使用
概述 Timer类的主要作用是设置计划任务,但封装任务的类却是TimerTask类.执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类. 方法schedule(ta ...
- 在Windows下同时安装Python2.x和Python3.x
前言: Python现在是两个版本共存,Python2.x和Python3.x都同时在更新.但是Python2.x和Python3.x的区别还是很多的(以后我可能会写一篇文章列举一下Python2.x ...
- pdf在线加载·
https://yq.aliyun.com/articles/40197 在线例子是这个
- spawn-fcgi运行fcgiwrap
http://linuxjcq.blog.51cto.com/3042600/718002 标签:休闲 spawn-fcgi fcgiwarp fcgi 职场 原创作品,允许转载,转载时请务必以超链接 ...
- Java 读书笔记 (八) 修饰符
Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 访问控制修饰符 default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符.使用对象.类.接口.变量.方法. ...
- C++中的内联函数和C中的宏定义的区别
在C++中内联函数: 内联函数即是在函数的声明和和定义前面加上“inline”关键字,内联函数和常规函数一样,都是按照值来传递参数的,如果参数为表达式,如4.5+7.5,则函数将传递表达式的值(这里为 ...
- Java并发编程(五)锁的使用(下)
显式锁 上篇讲了使用synchronized关键字来定义锁,其实Java除了使用这个关键字外还可以使用Lock接口及其实现的子类来定义锁,ReentrantLock类是Lock接口的一个实现,Reen ...
- OSI七层协议与TCP连接
概述 为了追求效率,我们写代码,不可能去关注底层知识,但往往到出了问题,或者性能调优.我们就会速手无策,仔细为自己查缺补漏,总结知识点. 网络协议 互联网的本质就是一系列的网络协议,让不同计算机能够互 ...