zoukankan      html  css  js  c++  java
  • 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 *);
    };
    
  • 相关阅读:
    Vim+Vundle+YouCompleteMe 安装
    TortoiseSVN 的分支合并操作
    JSP数据交互一
    Jquery操作DOM
    Jquery
    JQuery选择器
    第五章初始JQuery
    JavaScript对象及初识面向对象
    JavaScript第三章操作DOM
    JavaScript第二章操作BOM
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/10790115.html
Copyright © 2011-2022 走看看