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的devicestruct 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使用的初始化频率/** OCR(Operating Conditions Register)* 是MMC/SD/SDIO卡的一个32-bit的寄存器,* 其中有些bit指明了该卡的操作电压。* MMC host在驱动这些卡的时候,* 需要和Host自身所支持的电压范围匹配之后,* 才能正常操作,这就是ocr_avail的存在意义*/u32            ocr_avail;          // 该host可支持的操作电压范围/* * 如果MMC host针对SDIO、SD、MMC等不同类型的卡,* 所支持的电压范围不同的话,* 需要通过这几个字段特别指定。* 否则,不需要赋值(初始化为0)*/u32          ocr_avail_sdio; /* SDIO-specific OCR */u32          ocr_avail_sd;   /* SD-specific OCR */u32            ocr_avail_mmc;  /* MMC-specific OCR */
#ifdef CONFIG_PM_SLEEPstruct notifier_block pm_notify;// 用于支持power management有关的notify实现
#endifu32           max_current_330;    // 3.3V时的最大电流u32            max_current_300;    // 3.0V时的最大电流u32            max_current_180;    // 1.8V时的最大电流#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 */// 指示该MMC host所支持的功能特性u32            caps;       /* Host capabilities */#define MMC_CAP_4_BIT_DATA   (1 << 0)  /* Can the host do 4 bit transfers */
#define MMC_CAP_MMC_HIGHSPEED   (1 << 1)  /* Can do MMC high-speed timing */
#define MMC_CAP_SD_HIGHSPEED    (1 << 2)  /* Can do SD high-speed timing */
#define MMC_CAP_SDIO_IRQ    (1 << 3)  /* Can signal pending SDIO IRQs */
#define MMC_CAP_SPI     (1 << 4)  /* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL  (1 << 5)  /* Needs polling for card-detection */
#define MMC_CAP_8_BIT_DATA  (1 << 6)  /* Can the host do 8 bit transfers */
#define MMC_CAP_AGGRESSIVE_PM   (1 << 7)  /* Suspend (e)MMC/SD at idle  */
#define MMC_CAP_NONREMOVABLE    (1 << 8)  /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9)  /* Waits while card is busy */
#define MMC_CAP_ERASE       (1 << 10) /* Allow erase/trim commands */
#define MMC_CAP_3_3V_DDR    (1 << 11) /* Host supports eMMC DDR 3.3V */
#define MMC_CAP_1_8V_DDR    (1 << 12) /* Host supports eMMC DDR 1.8V */
#define MMC_CAP_1_2V_DDR    (1 << 13) /* Host supports eMMC DDR 1.2V */
#define MMC_CAP_POWER_OFF_CARD  (1 << 14) /* Can power off after boot */
#define MMC_CAP_BUS_WIDTH_TEST  (1 << 15) /* CMD14/CMD19 bus width ok */
#define MMC_CAP_UHS_SDR12   (1 << 16) /* Host supports UHS SDR12 mode */
#define MMC_CAP_UHS_SDR25   (1 << 17) /* Host supports UHS SDR25 mode */
#define MMC_CAP_UHS_SDR50   (1 << 18) /* Host supports UHS SDR50 mode */
#define MMC_CAP_UHS_SDR104  (1 << 19) /* Host supports UHS SDR104 mode */
#define MMC_CAP_UHS_DDR50   (1 << 20) /* Host supports UHS DDR50 mode */
#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) /* Synced runtime PM suspends. */
#define MMC_CAP_NEED_RSP_BUSY   (1 << 22) /* Commands with R1B can't use R1. */
#define MMC_CAP_DRIVER_TYPE_A   (1 << 23) /* Host supports Driver Type A */
#define MMC_CAP_DRIVER_TYPE_C   (1 << 24) /* Host supports Driver Type C */
#define MMC_CAP_DRIVER_TYPE_D   (1 << 25) /* Host supports Driver Type D */
#define MMC_CAP_DONE_COMPLETE   (1 << 27) /* RW reqs can be completed within mmc_request_done() */
#define MMC_CAP_CD_WAKE     (1 << 28) /* Enable card detect wake */
#define MMC_CAP_CMD_DURING_TFR  (1 << 29) /* Commands during data transfer */
#define MMC_CAP_CMD23       (1 << 30) /* CMD23 supported. */
#define MMC_CAP_HW_RESET    (1 << 31) /* Hardware reset */// 指示该MMC host所支持的功能特性u32           caps2;      /* More host capabilities */#define MMC_CAP2_BOOTPART_NOACC (1 << 0)  /* Boot partition no access */
#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2)  /* Can do full power cycle */
#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_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_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
#define MMC_CAP2_HS400_1_8V (1 << 15) /* Can support HS400 1.8V */
#define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */
#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)   /* No physical write protect pin, assume that card is always read-write */
#define MMC_CAP2_NO_SDIO    (1 << 19) /* Do not send SDIO commands during initialization */
#define MMC_CAP2_HS400_ES   (1 << 20) /* Host supports enhanced strobe */
#define MMC_CAP2_NO_SD      (1 << 21) /* Do not send SD commands during initialization */
#define MMC_CAP2_NO_MMC     (1 << 22) /* Do not send (e)MMC commands during initialization */
#define MMC_CAP2_CQE        (1 << 23) /* Has eMMC command queue engine */
#define MMC_CAP2_CQE_DCMD   (1 << 24) /* CQE can issue a direct command */
#define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */
#define MMC_CAP2_MERGE_CAPABLE  (1 << 26) /* Host can merge a segment over the segment size */int         fixed_drv_type; /* fixed driver type for non-removable media */// 该host所支持的电源管理特性mmc_pm_flag_t      pm_caps;    /* supported pm features *//* 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_busy_timeout; /* max busy timeout in ms *//* private data */// 该host的bus使用的锁spinlock_t      lock;       /* lock for claim and bus ops */// 用于保存MMC bus的当前配置struct mmc_ios       ios;        /* current io bus settings *//* 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是否处于激活状态unsigned int     can_retune:1;   /* re-tuning can be used */unsigned int     doing_retune:1; /* re-tuning in progress */unsigned int     retune_now:1;   /* do re-tuning at next req */unsigned int      retune_paused:1; /* re-tuning is temporarily disabled */unsigned int        use_blk_mq:1;   /* use blk-mq */unsigned int        retune_crc_disable:1; /* don't trigger retune upon crc */unsigned int      can_dma_map_merge:1; /* merging can be used */int           rescan_disable; /* disable card detection */        // 禁止rescan的标识,禁止搜索cardint           rescan_entered; /* used with nonremovable devices */// 是否已经rescan过的标识,对应不可移除的设备只能rescan一次int         need_retune;    /* re-tuning is needed */int            hold_retune;    /* hold off re-tuning */unsigned int        retune_period;  /* re-tuning period in secs */struct timer_list retune_timer;   /* for periodic re-tuning */bool            trigger_card_event; /* card_event necessary */struct mmc_card       *card;      /* device attached to this host */// 和该host绑定在一起的cardwait_queue_head_t  wq;struct mmc_ctx       *claimer;   /* context that has host claimed */// 该host的占有者进程int            claim_cnt;  /* "claim" nesting count */// 占有者进程对该host的占用计数struct mmc_ctx      default_ctx;    /* default context */struct delayed_work    detect; // 检测卡槽变化的工作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     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;   /* requested pm features */struct led_trigger   *led;       /* activity led */#ifdef CONFIG_REGULATORbool           regulator_enabled; /* regulator state */ // 代表regulator(LDO)的状态
#endifstruct mmc_supply supply;struct dentry        *debugfs_root;  // 对应的debug目录结构体/* Ongoing data transfer that allows commands during transfer */struct mmc_request  *ongoing_mrq;#ifdef CONFIG_FAIL_MMC_REQUESTstruct fault_attr    fail_mmc_request;
#endifunsigned int      actual_clock;   /* Actual HC clock rate */unsigned int      slotno; /* used for sdio acpi binding */int         dsr_req;    /* DSR value is valid */u32         dsr;    /* optional driver stage (DSR) value *//* Command Queue Engine (CQE) support */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 {/** 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是为了实现异步请求处理而设置的,是非必需的,// 异步请求处理就是指,当另外一个异步请求还没有处理完成的时候,// 可以先准备另外一个异步请求而不必等待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);/** Avoid calling the next three functions too often or in a "fast* path", since underlaying controller might implement them in an* expensive and/or slow way. Also note that these functions might* sleep, so don't call them in the atomic contexts!*//** Notes to the set_ios callback:* ios->clock might be 0. For some controllers, setting 0Hz* as any other frequency works. However, some controllers* explicitly need to disable the clock. Otherwise e.g. voltage* switching might fail because the SDCLK is not really quiet.*/// 设置host的总线的io settingvoid  (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);/** Return values for the get_ro callback should be:*   0 for a read/write card*   1 for a read-only card*   -ENOSYS when not supported (equal to NULL callback)*   or a negative errno value when something bad happened*/int   (*get_ro)(struct mmc_host *host); // 获取host上的card的读写属性/** Return values for the get_cd callback should be:*   0 for a absent card*   1 for a present card*   -ENOSYS when not supported (equal to NULL callback)*   or a negative errno value when something bad happened*/int  (*get_cd)(struct mmc_host *host); // 检测host的卡槽中card的插入状态void    (*enable_sdio_irq)(struct mmc_host *host, int enable);/* Mandatory callback when using MMC_CAP2_SDIO_IRQ_NOTHREAD. */void   (*ack_sdio_irq)(struct mmc_host *host);/* optional callback for HC quirks */ // 初始化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);/* 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 */// 执行tuning操作,为card选择一个合适的采样点int   (*execute_tuning)(struct mmc_host *host, u32 opcode);/* Prepare HS400 target operating frequency depending host driver */int    (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);/* Prepare switch to DDR during the HS400 init sequence */int   (*hs400_prepare_ddr)(struct mmc_host *host);/* Prepare for switching from HS400 to HS200 */void (*hs400_downgrade)(struct mmc_host *host);/* Complete selection of HS400 */void (*hs400_complete)(struct mmc_host *host);/* Prepare enhanced strobe depending host driver */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);   // 硬件复位/** Optional callback to support controllers with HW issues for multiple* I/O. Returns the number of supported blocks for the request.*/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设备。

/** MMC device*/
struct mmc_card {struct mmc_host        *host;      /* the host this device belongs to */ // 该mmc_card所属hoststruct device       dev;        /* the device */ // 对应的deviceu32            ocr;        /* the current OCR setting */unsigned int       rca;        /* relative card address of device */unsigned int       type;       /* card type */ // card类型
#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 */unsigned int       state;      /* (our) card state */ // card的当前状态unsigned int     quirks;     /* card quirks */ // 该card的一些特点unsigned int     quirk_max_rate; /* max rate set by 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_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 *//* byte mode */
#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 */
#define MMC_QUIRK_BROKEN_IRQ_POLLING    (1<<11)   /* Polling SDIO_CCCR_INTx could create a fake interrupt */
#define MMC_QUIRK_TRIM_BROKEN   (1<<12)       /* Skip trim */
#define MMC_QUIRK_BROKEN_HPI    (1<<13)       /* Disable broken HPI support */bool            reenable_cmdq;  /* Re-enable Command Queue */unsigned int       erase_size; /* erase size in sectors */unsigned int     erase_shift;    /* if erase unit is power 2 */unsigned int      pref_erase; /* in sectors */unsigned int        eg_boundary;    /* don't cross erase-group boundaries */unsigned int       erase_arg;  /* erase / trim / discard */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寄存器的值u32            raw_ssr[16];    /* raw card SSR */ // 原始的ssr寄存器的值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 */ // 外部sd card的信息struct sd_ssr     ssr;        /* yet more SD information */ // 更多关于sd card的信息struct sd_switch_caps    sw_caps;    /* switch (CMD6) caps */  // sd的切换属性unsigned int        sdio_funcs; /* number of SDIO functions */ // sdio funcs的数量atomic_t     sdio_funcs_probed; /* number of probed SDIO funcs */struct sdio_cccr    cccr;       /* common card info */struct sdio_cis       cis;        /* common tuple info */struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ //sdio func指针struct sdio_func    *sdio_single_irq; /* SDIO function when only one IRQ active */unsigned      num_info;   /* number of info strings */const char      **info;     /* info strings */struct sdio_func_tuple    *tuples;    /* unknown common tuples */unsigned int     sd_bus_speed;   /* Bus Speed Mode set for the card */unsigned int       mmc_avail_type; /* supported device type by both host and card */unsigned int       drive_strength; /* for UHS-I, HS200 or HS400 */struct dentry        *debugfs_root; // 对应debug目录的结构体struct mmc_part  part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ // 物理分区unsigned int    nr_parts; // 分区数量unsigned int     bouncesz;   /* Bounce buffer size */struct workqueue_struct *complete_wq;   /* Private workqueue */
};

host的总线相关

struct mmc_bus_ops

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

struct mmc_bus_ops {void (*remove)(struct mmc_host *); // 从软件上注销mmc总线上的cardvoid (*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;          /* clock rate */ // 当前工作频率unsigned short    vdd;            // 支持的电压表unsigned int   power_delay_ms;     /* waiting for stable power *//* vdd stores the bit number of the selected voltage range from below. */unsigned char    bus_mode;       /* command output mode */ // 总线输出模式,包括开漏模式和上拉模式#define MMC_BUSMODE_OPENDRAIN 1
#define MMC_BUSMODE_PUSHPULL    2unsigned char  chip_select;        /* SPI chip select */ // spi片选#define MMC_CS_DONTCARE       0
#define MMC_CS_HIGH     1
#define MMC_CS_LOW      2unsigned char  power_mode;     /* power supply mode */ // 电源状态模式#define MMC_POWER_OFF      0
#define MMC_POWER_UP        1
#define MMC_POWER_ON        2
#define MMC_POWER_UNDEFINED 3unsigned char  bus_width;      /* data bus width */ // 总线宽度#define MMC_BUS_WIDTH_1     0
#define MMC_BUS_WIDTH_4     2
#define MMC_BUS_WIDTH_8     3unsigned char  timing;         /* timing specification used */ // 时序类型#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    10unsigned char signal_voltage;     /* signalling voltage (1.8V or 3.3V) */ // 信号的工作电压#define MMC_SIGNAL_VOLTAGE_330    0
#define MMC_SIGNAL_VOLTAGE_180  1
#define MMC_SIGNAL_VOLTAGE_120  2unsigned char  drv_type;       /* driver type (A, B, C, D) */ // 驱动类型#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   3bool enhanced_strobe;          /* hs400es selection */
};

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;      /* expected response type */
#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_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)#define MMC_RSP_SPI_S1    (1 << 7)      /* one status byte */
#define MMC_RSP_SPI_S2  (1 << 8)      /* second byte */
#define MMC_RSP_SPI_B4  (1 << 9)      /* four data bytes */
#define MMC_RSP_SPI_BUSY (1 << 10)        /* card may send busy *//** These are the native response types, and correspond to valid bit* patterns of the above flags.  One additional valid pattern* is all zeros, which means we don't expect a response.*/
#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)/* Can be used by core to poll after switch to MMC HS mode */
#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))/** These are the SPI response types for MMC, SD, and SDIO cards.* Commands return R1, with maybe more info.  Zero is an error type;* callers must always provide the appropriate MMC_RSP_SPI_Rx flags.*/
#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))/** These are the command types.*/
#define mmc_cmd_type(cmd)   ((cmd)->flags & MMC_CMD_MASK)unsigned int        retries;    /* max number of retries */ // 失败时的重复尝试次数int            error;      /* command error */ // 命令的错误码/** Standard errno values are used for errors, but some have specific* meaning in the MMC layer:** ETIMEDOUT    Card took too long to respond* EILSEQ       Basic format problem with the received or sent data*              (e.g. CRC check failed, incorrect opcode in response*              or bad end bit)* EINVAL       Request cannot be performed because of restrictions*              in hardware and/or the driver* ENOMEDIUM    Host can determine that the slot is empty and is*              actively failing requests*/unsigned int        busy_timeout;   /* busy detect timeout in ms *//* Set this flag only for blocking sanitize request */bool           sanitize_busy;// 和该命令关联在一起的数据段struct mmc_data       *data;      /* data segment associated with cmd */// 该命令关联到哪个requeststruct mmc_request  *mrq;       /* associated request */
};

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       blk_addr;   /* block address */    // card地址int         error;      /* data error */unsigned int        flags;      // 传输标识#define MMC_DATA_WRITE       BIT(8)
#define MMC_DATA_READ       BIT(9)
/* Extra flags used by CQE */
#define MMC_DATA_QBR        BIT(10)     /* CQE queue barrier*/
#define MMC_DATA_PRIO       BIT(11)     /* CQE high priority */
#define MMC_DATA_REL_WR     BIT(12)     /* Reliable write */
#define MMC_DATA_DAT_TAG    BIT(13)     /* Tag request */
#define MMC_DATA_FORCED_PRG BIT(14)     /* Forced programming */unsigned int        bytes_xfered;struct mmc_command *stop;      /* stop command */      // 结束传输的命令struct mmc_request    *mrq;       /* associated request */// 该命令关联到哪个requestunsigned int      sg_len;     /* size of scatter list */ sg数组的sizeint         sg_count;   /* mapped sg entries */ // 通过sg map出来的实际的entry的个struct scatterlist  *sg;        /* I/O scatter list */ //一个struct scatterlist类型的数组s32           host_cookie;    /* host private data */ // host driver的私有数据
};

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;      // 要传输的stop命令struct completion  completion; // 完成量struct completion cmd_completion;// 传输结束后的回调函数void            (*done)(struct mmc_request *);/* completion function *//** Notify uppers layers (e.g. mmc block driver) that recovery is needed* due to an error associated with the mmc_request. Currently used only* by CQE.*/void            (*recovery_notifier)(struct mmc_request *);struct mmc_host      *host; // 所属host/* Allow other commands during this ongoing data transfer or busy wait */bool           cap_cmd_during_tfr;int          tag;
};

Linux驱动——mmc数据结构(二)相关推荐

  1. Linux驱动——mmc概念与框架(一)

    Linux驱动--mmc概念与框架(一) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: Linux MMC framewo ...

  2. Linux驱动——mmc host controller(九)

    Linux驱动--mmc host controller(九) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0 文章目录 Linux驱动--mmc ...

  3. Linux驱动——mmc sd card初始化流程(十一)

    Linux驱动--mmc sd card初始化流程(十一) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客:   (1)[sd ...

  4. Linux驱动——mmc card热插拔检测机制(十)

    Linux驱动--mmc card热插拔检测机制(十) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: [sd card] ...

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

    Linux驱动--mmc sd card 块设备读写流程(十三) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客:   (1) ...

  6. 【嵌入式Linux驱动入门】二、上手Hello驱动,了解驱动开发流程

      我们知道他们在说谎,他们也知道他们在说谎,他们知道我们知道他们在说谎,我们也知道他们知道我们知道他们在说谎,但是他们依然在说谎. 文章目录 一.Linux驱动分类 二.Linux驱动初探 三.He ...

  7. 【嵌入式Linux驱动开发】二十一、Linux内核自带的KEY驱动探索

      君子应知进退方,时机不到且隐藏.   妆未梳成未见客,势弱稍时敛锋芒.   腹隐良谋待机至,东山再起斗志昂.   遥想曹刘煮酒事,高明刘备扮愚郎. 文章目录 一. Linux 内核自带 KEY 驱 ...

  8. 【嵌入式Linux驱动开发】二十四、Linux I2C 驱动上手尝试

      人的前程关于眼界.关乎格局.   志之所趋,无远弗届,穷山复海不能限也:   志之所向,无坚不入,锐兵精甲不能御也. 一.I2C驱动框架简介   Linux内核将 I2C 驱动分为两部分: ①. ...

  9. Linux驱动开发(二)内核符号表

    内核符号表是内核中一个全局的总表,这个表中声明了一些全局的函数.内核中的驱动程序只需要用 extern 声明后就可以直接调用这些函数了. 查看内核中的符号表: cat /proc/kallsyms 将 ...

最新文章

  1. php bc函数库,PHP高精确度运算BC函数库实例详解
  2. Windows 窗体多线程
  3. 廖雪峰Java2面向对象编程-4抽象类和接口-1抽象类
  4. 重入锁、死锁、活锁、公平非公平锁……一下子都给你屡清楚了
  5. windows update失败还原更改,无法开机
  6. 如何成为一名合格的自动驾驶工程师
  7. 零碎的小知识点 ----------C# ToString()函数注意事项
  8. 代码补全_AI加持,Kite增加智能代码补全功能:减少一半操作,实时补全
  9. 【Android】11.3 屏幕旋转和场景变换过程中GridView的呈现
  10. 火狐浏览器中文乱码怎么办 Firefox中文乱码解决方法
  11. python nmap模块详解_python中的Nmap模块问题
  12. 如何让你的Linux云服务器更加的安全?
  13. 自定义按键连发工具_微软 PowerToys 增强工具,提升Win10 效率利器
  14. Widget改变大小
  15. css如何修改行内样式
  16. Windows10关闭80端口占用
  17. 第一章---近红外光谱分析概述1
  18. Microbiome:中国科学家完成鸡肠道微生物宏基因集的构建(张和平、魏泓、秦楠点评)...
  19. Python统计学01——数据可视化
  20. 支理解SVM的三层境界

热门文章

  1. 在Nignx增加http2模块顺便聊聊HTTP的八卦
  2. 不能装载文档控件。请在检查浏览器的选项中检查浏览器的安全设置_【网络安全知识系列(五)】如何正确设置浏览器!...
  3. 浏览器中访问本地文件for mac
  4. js实现精确统计网站访问量的代码分享
  5. 【项目笔记_答题器】rp552d usb hid 在seewo win10 设备上启动无法识别
  6. JS_SDK实现网站应用QQ登录功能-QQ互联(小白易懂)
  7. java给文件777权限_Linux常用命令:chmod修改文件权限 777和755分别是什么意思?
  8. c# U盘禁用---守护进程(插入,拔出,卸载等操作)
  9. net start mysql:无法启动
  10. 关于高精地图-导航电子地图制作测绘资质的讯息分享