Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1183506
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: LINUX

2016-11-07 14:55:38

 


图片

////
图片


//////////////////////////////////////////////////////////////////////////////////

本结构表述一张MMC卡
/*
 * MMC device
 */
struct mmc_card {
    //隶属的mmc控制器
    struct mmc_host        *host;        /* the host this device belongs to */
//当前设备
    struct device        dev;        /* the device */
//卡地址
    unsigned int        rca;        /* relative card address of device */
//卡类型
    unsigned int        type;        /* card type */
#define MMC_TYPE_MMC        0        /* MMC card */
#define MMC_TYPE_SD        1        /* SD card */
#define MMC_TYPE_SDIO        2        /* SDIO card */
//卡状态
    unsigned int        state;        /* (our) 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 */
//卡CID 未解码
    u32            raw_cid[4];    /* raw card CID */
//卡CSD 未解码
    u32            raw_csd[4];    /* raw card CSD */
//卡SCR 未解码
    u32            raw_scr[2];    /* raw card SCR */
//卡 身份 已解码
    struct mmc_cid        cid;        /* card identification */
//卡的特殊数据 已解码
    struct mmc_csd        csd;        /* card specific */
    struct mmc_ext_csd    ext_csd;    /* mmc v4 extended card specific */
//额外的SD卡数据 已解码
    struct sd_scr        scr;        /* extra SD information */
    struct sd_switch_caps    sw_caps;    /* switch (CMD6) caps */

    unsigned int        sdio_funcs;    /* number of SDIO functions */
    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) */
    unsigned        num_info;    /* number of info strings */
    const char        **info;        /* info strings */
    struct sdio_func_tuple    *tuples;    /* unknown common tuples */

    struct dentry        *debugfs_root;
};

//////////////////////////////////////////////////////////////////////////////////////////////////////

struct mmc_cid {
    unsigned int        manfid;//制造商ID
    char            prod_name[8];//产品名
    unsigned int        serial;//产品序列号
    unsigned short        oemid;//产品OID
    unsigned short        year;
    unsigned char        hwrev;
    unsigned char        fwrev;
    unsigned char        month;
};
/////////////

struct mmc_csd {
    unsigned char        mmca_vsn;//卡版本号
    unsigned short        cmdclass;//card支持的命令子集
    unsigned short        tacc_clks;//用于计算读命令的末位和所读数据的首位间的最大时值nac
    unsigned int        tacc_ns;
    unsigned int        r2w_factor;
    unsigned int        max_dtr;//最大传输速率
    unsigned int        read_blkbits;//最大的读数据块长度
    unsigned int        write_blkbits;//最大的写数据块长度
    unsigned int        capacity;//卡的存储容量
    unsigned int        read_partial:1,//读小块尺寸数据(最小1bite)是否允许,SD卡此处恒为1
                read_misalign:1,
                write_partial:1,
                write_misalign:1;
};
/////////////

struct sd_scr {
    unsigned char        sda_vsn;//physical layer specification版本号
    unsigned char        bus_widths;//数据线的宽度
#define SD_SCR_BUS_WIDTH_1    (1<<0)
#define SD_SCR_BUS_WIDTH_4    (1<<2)
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
 * There is one mmc_blk_data per slot.
 */
struct mmc_blk_data {
    spinlock_t    lock;
    struct gendisk    *disk; //通用磁盘
    struct mmc_queue queue;//磁盘设备的请求队列数据结构

    unsigned int    usage;
    unsigned int    read_only;//只读标志
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////

struct gendisk {
    /* major, first_minor and minors are input parameters only,
     * don't use directly.  Use disk_devt() and disk_max_parts().
     */
    int major;            /* major number of driver */ 磁盘的主设备号       
    int first_minor;//磁盘的第一个次设备号
//次设备号个数,即分区个数
    int minors;                     /* maximum number of minors, =1 for
                                         * disks that can't be partitioned. */
//磁盘名
    char disk_name[DISK_NAME_LEN];    /* name of major driver */

    /* Array of pointers to partitions indexed by partno.
     * Protected with matching bdev lock but stat and other
     * non-critical accesses use RCU.  Always access through
     * helpers.
     */
//指向磁盘分区表
    struct disk_part_tbl *part_tbl;
//第一个分区 0分区
    struct hd_struct part0;
//磁盘块设备操作方法
    struct block_device_operations *fops;
//指向磁盘设备的请求队列
    struct request_queue *queue;
//磁盘的私有数据
    void *private_data;
//磁盘类别标识
    int flags;
//对应的当前设备
    struct device *driverfs_dev;  // FIXME: remove
    struct kobject *slave_dir;

    struct timer_rand_state *random;

    atomic_t sync_io;        /* RAID */
    struct work_struct async_notify;
#ifdef  CONFIG_BLK_DEV_INTEGRITY
    struct blk_integrity *integrity;
#endif
    int node_id;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////

struct mmc_queue {
    struct mmc_card        *card;//对应的卡设备
    struct task_struct    *thread;//请求队列关联的处理线程
    struct semaphore    thread_sem;
    unsigned int        flags;
    struct request        *req;//取出的第一个请求
//发送请求的函数
    int            (*issue_fn)(struct mmc_queue *, struct request *);
//这里用来保存mmc_blk_data{}的指针
    void            *data;
//磁盘设备的请求队列
    struct request_queue    *queue;
//磁盘设备的散列表
    struct scatterlist    *sg;
    char            *bounce_buf;
    struct scatterlist    *bounce_sg;
    unsigned int        bounce_sg_len;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
static int __devinit sdhci_s3c_probe(struct platform_device *pdev) ------->
struct sdhci_host *sdhci_alloc_host(struct device *dev, size_t priv_size) -------->
mmc_alloc_host 函数申请了mmc_host结构内核空间

//mmc_host用于描述MMC接口 CPU一侧的设备,它可以看成是class device的特例
//包含了 struct mmc_card        *card;        /* device attached to this host */结构成员
//一个mmc_host代表一个mmc控制器
struct mmc_host {
    struct device        *parent;
    struct device        class_dev;//当前mmc控制器设备
    int            index;
    const struct mmc_host_ops *ops;//控制器的操作方法
    unsigned int        f_min;
    unsigned int        f_max;
//控制器支持的运行电压
    u32            ocr_avail;

#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 */

    unsigned long        caps;        /* Host capabilities */主机(SD主模式) 传输能力

#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_ON_BOARD    (1 << 7)    /* Do not need to rescan after bootup */
#define MMC_CAP_BOOT_ONTHEFLY    (1 << 8)    /* Can detect device at boot time */

    /* host specific block data */
//最大的数据段尺寸bytes
    unsigned int        max_seg_size;    /* see blk_queue_max_segment_size */
//一条请求的硬件扇区数上限(通常512b为单位)
    unsigned short        max_hw_segs;    /* see blk_queue_max_hw_segments */
    unsigned short        max_phys_segs;    /* see blk_queue_max_phys_segments */
    unsigned short        unused;
//一条请求的最大字节数bytes
    unsigned int        max_req_size;    /* maximum number of bytes in one req */
//一个mmc块的最大尺寸bytes
    unsigned int        max_blk_size;    /* maximum size of one mmc block */
//一条请求中的数据块数目上限
    unsigned int        max_blk_count;    /* maximum number of blocks in one req */

    /* private data */
    spinlock_t        lock;        /* lock for claim and bus ops */
//当前的总线设置
    struct mmc_ios        ios;        /* current io bus settings */
//OCR寄存器在SD卡手册里
    u32            ocr;        /* the current OCR setting */

    /* group bitfields together to minimize padding */
    unsigned int        use_spi_crc:1;
//控制器咱用标志
    unsigned int        claimed:1;    /* host exclusively(唯一的,特定的) claimed (声 称; 夺走; 要求)*/
//控制器总线被释放
    unsigned int        bus_dead:1;    /* bus has been released */
#ifdef CONFIG_MMC_DEBUG
    unsigned int        removed:1;    /* host is being removed */
#endif
//与控制器关联的卡
    struct mmc_card        *card;        /* device attached to this host */
//声明占用控制器的等待队列头节点
    wait_queue_head_t    wq;
//延迟的事务,用于探测
    struct delayed_work    detect;
//当前绑定的总线操作
    const struct mmc_bus_ops *bus_ops;    /* current bus driver */
//应用计数
    unsigned int        bus_refs;    /* reference counter */

    unsigned int        sdio_irqs;
    struct task_struct    *sdio_irq_thread;
    atomic_t        sdio_irq_thread_abort;

#ifdef CONFIG_LEDS_TRIGGERS
    struct led_trigger    *led;        /* activity led */
#endif

    struct dentry        *debugfs_root;

    unsigned long        private[0] ____cacheline_aligned;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mmc_host发送命令和数据是通过 struct mmc_host_ops 操作

static const struct mmc_host_ops   sdhci_ops = {
//request函数指针指向的函数用来处理host向从设备发送命令的请求,
    .request    = sdhci_request,
//set_ios用来设置电源、时钟等等之类(需要重点关注),
    .set_ios    = sdhci_set_ios,
// get_ro用来判断是否写保护
    .get_ro        = sdhci_get_ro,
    .enable_sdio_irq = sdhci_enable_sdio_irq,
};
///////////

struct mmc_host_ops {
//控制器处理请求的接口
    void    (*request)(struct mmc_host *host, struct mmc_request *req);
    /*
     * Avoid calling these 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!
     *
     * 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
     *
     * 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
     */
//控制器总线设置的接口
    void    (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
// get_ro用来判断是否写保护
    int    (*get_ro)(struct mmc_host *host);
    int    (*get_cd)(struct mmc_host *host);

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

struct mmc_bus_ops {
//释放卡
    void (*remove)(struct mmc_host *);
//查询卡的状态
    void (*detect)(struct mmc_host *);
//使卡退出传输状态,即挂起
    void (*suspend)(struct mmc_host *);
//恢复状态
    void (*resume)(struct mmc_host *);
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

存储mmc卡的状态信息
struct mmc_ios {
    unsigned int    clock;            /* clock rate */时钟
    unsigned short    vdd;//电压

/* 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    2
//SPI芯片片选
    unsigned char    chip_select;        /* SPI chip select */

#define MMC_CS_DONTCARE        0
#define MMC_CS_HIGH        1
#define MMC_CS_LOW        2

    unsigned char    power_mode;        /* power supply mode */

#define MMC_POWER_OFF        0
#define MMC_POWER_UP        1
#define MMC_POWER_ON        2
//总线宽度1,4,8
    unsigned char    bus_width;        /* data bus width */

#define MMC_BUS_WIDTH_1        0
#define MMC_BUS_WIDTH_4        2
#define MMC_BUS_WIDTH_8        3
//时序模式
    unsigned char    timing;            /* timing specification used */

#define MMC_TIMING_LEGACY    0
#define MMC_TIMING_MMC_HS    1
#define MMC_TIMING_SD_HS    2
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////
drivers/mmc/core/bus.c
static struct bus_type mmc_bus_type = {
 .name  = "mmc",
 .dev_attrs = mmc_dev_attrs,
 .match  = mmc_bus_match,//匹配函数
 .uevent  = mmc_bus_uevent,
 .probe  = mmc_bus_probe,//匹配到之后的处理
 .remove  = mmc_bus_remove,
 .suspend = mmc_bus_suspend,
 .resume  = mmc_bus_resume,
};
/////////

struct bus_type {
    const char        *name;
    struct bus_attribute    *bus_attrs;
    struct device_attribute    *dev_attrs;
    struct driver_attribute    *drv_attrs;

    int (*match)(struct device *dev, struct device_driver *drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);

    int (*suspend)(struct device *dev, pm_message_t state);
    int (*suspend_late)(struct device *dev, pm_message_t state);
    int (*resume_early)(struct device *dev);
    int (*resume)(struct device *dev);

    struct pm_ext_ops *pm;

    struct bus_type_private *p;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct device_driver {
    const char        *name;
    struct bus_type        *bus;

    struct module        *owner;
    const char         *mod_name;    /* used for built-in modules */

    int (*probe) (struct device *dev);
    int (*remove) (struct device *dev);
    void (*shutdown) (struct device *dev);
    int (*suspend) (struct device *dev, pm_message_t state);
    int (*resume) (struct device *dev);
    struct attribute_group **groups;

    struct pm_ops *pm;

    struct driver_private *p;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////drivers/mmc/card/block.c
static struct mmc_driver mmc_driver = {
 .drv  = {
  .name = "mmcblk",
 },
 .probe  = mmc_blk_probe,
 .remove  = mmc_blk_remove,
 .suspend = mmc_blk_suspend,
 .resume  = mmc_blk_resume,
};
////////////////////


/*
 * MMC device driver (e.g., Flash card, I/O card...)
 */
struct mmc_driver {
    struct device_driver drv;//当前驱动
    int (*probe)(struct mmc_card *);//驱动的匹配到之后的处理函数
    void (*remove)(struct mmc_card *);
    int (*suspend)(struct mmc_card *, pm_message_t);
    int (*resume)(struct mmc_card *);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct mmc_command {
    u32            opcode;//命令操作码
    u32            arg;//命令参数
    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)

#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 */
//命令出错
    unsigned 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
 */
//命令关联的数据段
    struct mmc_data        *data;        /* data segment associated with cmd */
//关联的请求
    struct mmc_request    *mrq;        /* associated request */
};
 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


 
struct mmc_data {
    unsigned int        timeout_ns;    /* data timeout (in ns, max 80ms) */超时时间
    unsigned int        timeout_clks;    /* data timeout (in clocks) */ 超时时钟数
    unsigned int        blksz;        /* data block size */块尺寸
    unsigned int        blocks;        /* number of blocks */块数目
    unsigned int        error;        /* data error */数据错误
    unsigned int        flags;//读写标志

#define MMC_DATA_WRITE    (1 << 8)
#define MMC_DATA_READ    (1 << 9)
#define MMC_DATA_STREAM    (1 << 10)
//待传输的字节数
    unsigned int        bytes_xfered;

    struct mmc_command    *stop;        /* stop command */stop命令
    struct mmc_request    *mrq;        /* associated request */关联的请求

    unsigned int        sg_len;        /* size of scatter list */散列表的尺寸
    struct scatterlist    *sg;        /* I/O scatter list */
散列表指针
 
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 


 
struct mmc_request {
    struct mmc_command    *cmd;
//请求对应的命令的指针   
    struct mmc_data        *data;
//请求对应的数据的指针   
   struct mmc_command    *stop;
//请求对应的stop命令的指针
    void            *done_data;    /* completion data */完成量  的数据
    void            (*done)(struct mmc_request *);/* completion function */ 完成量 指针函数
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct mmc_blk_request {
    struct mmc_request    mrq;
//当前请求
 
    struct mmc_command    cmd;
//请求对应的命令
 
    struct mmc_command    stop;//请求的stop命令
    struct mmc_data        data;//请求对应的数据
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 

struct sdhci_s3c {
    struct sdhci_host    *host;
    struct platform_device    *pdev;
    struct resource        *ioarea;
    struct s3c_sdhci_platdata *pdata;
    unsigned int        cur_clk;

    struct clk        *clk_io;    /* clock for io bus */
    struct clk        *clk_bus[MAX_BUS_CLK];
};
//////

static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//这应该是描述host端SD卡的?
//有成员
    /* Internal data */ struct mmc_host        *mmc;        /* MMC structure */
struct sdhci_host {
    /* Data set by hardware interface driver */
    const char        *hw_name;    /* Hardware bus name */

    unsigned int        quirks;        /* Deviations from spec. */

/* Controller doesn't honor resets unless we touch the clock register */
#define SDHCI_QUIRK_CLOCK_BEFORE_RESET            (1<<0)
/* Controller has bad caps bits, but really supports DMA */
#define SDHCI_QUIRK_FORCE_DMA                (1<<1)
/* Controller doesn't like to be reset when there is no card inserted. */
#define SDHCI_QUIRK_NO_CARD_NO_RESET            (1<<2)
/* Controller doesn't like clearing the power reg before a change */
#define SDHCI_QUIRK_SINGLE_POWER_WRITE            (1<<3)
/* Controller has flaky internal state so reset it on each ios change */
#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS        (1<<4)
/* Controller has an unusable DMA engine */
#define SDHCI_QUIRK_BROKEN_DMA                (1<<5)
/* Controller has an unusable ADMA engine */
#define SDHCI_QUIRK_BROKEN_ADMA                (1<<6)
/* Controller can only DMA from 32-bit aligned addresses */
#define SDHCI_QUIRK_32BIT_DMA_ADDR            (1<<7)
/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
#define SDHCI_QUIRK_32BIT_DMA_SIZE            (1<<8)
/* Controller can only ADMA chunks that are a multiple of 32 bits */
#define SDHCI_QUIRK_32BIT_ADMA_SIZE            (1<<9)
/* Controller needs to be reset after each request to stay stable */
#define SDHCI_QUIRK_RESET_AFTER_REQUEST            (1<<10)
/* Controller needs voltage and power writes to happen separately */
#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER        (1<<11)
/* Controller provides an incorrect timeout value for transfers */
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL            (1<<12)
/* Controller has an issue with buffer bits for small transfers */
#define SDHCI_QUIRK_BROKEN_SMALL_PIO            (1<<13)
/* Controller supports high speed but doesn't have the caps bit set */
#define SDHCI_QUIRK_FORCE_HIGHSPEED            (1<<14)
/* Controller does not provide transfer-complete interrupt when not busy */
#define SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY        (1<<15)

    int            irq;        /* Device IRQ */
    void __iomem *        ioaddr;        /* Mapped address */

    const struct sdhci_ops    *ops;        /* Low level hw interface */

    /* Internal data */
    struct mmc_host        *mmc;        /* MMC structure */
    u64            dma_mask;    /* custom DMA mask */

#ifdef CONFIG_LEDS_CLASS
    struct led_classdev    led;        /* LED control */
#endif

    spinlock_t        lock;        /* Mutex */

    int            flags;        /* Host attributes */
#define SDHCI_USE_DMA        (1<<0)        /* Host is DMA capable */
#define SDHCI_USE_ADMA        (1<<1)        /* Host is ADMA capable */
#define SDHCI_REQ_USE_DMA    (1<<2)        /* Use DMA for this req. */
#define SDHCI_DEVICE_DEAD    (1<<3)        /* Device unresponsive */
#define SDHCI_DEVICE_ALIVE    (1<<4)        /* used on ext card detect */

    unsigned int        version;    /* SDHCI spec. version */

    unsigned int        max_clk;    /* Max possible freq (MHz) */
    unsigned int        timeout_clk;    /* Timeout freq (KHz) */

    unsigned int        clock;        /* Current clock (MHz) */
    unsigned short        power;        /* Current voltage */

    struct mmc_request    *mrq;        /* Current request */
    struct mmc_command    *cmd;        /* Current command */
    struct mmc_data        *data;        /* Current data request */
    unsigned int        data_early:1;    /* Data finished before cmd */

    struct sg_mapping_iter    sg_miter;    /* SG state for PIO */
    unsigned int        blocks;        /* remaining PIO blocks */

    int            sg_count;    /* Mapped sg entries */

    u8            *adma_desc;    /* ADMA descriptor table */
    u8            *align_buffer;    /* Bounce buffer */

    dma_addr_t        adma_addr;    /* Mapped ADMA descr. table */
    dma_addr_t        align_addr;    /* Mapped bounce buffer */

    struct tasklet_struct    card_tasklet;    /* Tasklet structures */
    struct tasklet_struct    finish_tasklet;

    struct timer_list    timer;        /* Timer for timeouts */

    unsigned long        private[0] ____cacheline_aligned;
};
///

驱动注册后,在平台总线找哦你查找SDIO控制器设备,如果找到,就会调用sdhci_s3c_probe(struct platform_device*pdev)函数,这个函数完成下面提到的三个结构体的初始化和注册工作,最终添加到设备模型中
static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
{
    struct sdhci_host *host;
    struct sdhci_s3c *sc;
//申请空间
//从传入的参数可以知道,
//sdhci_alloc_host(dev, sizeof(structsdhci_s3c))函数返回后,
//系统为struct sdhci_s3c 、struct sdhci_host、struct mmc_host分配了连续的存储空间,
//而且有结构体里的struct mmc_host结构体的private数组存储struct sdhci_host,
//后者的private存储struct sdhci_s3c

    host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
    sc = sdhci_priv(host);
}
////

static inline void *sdhci_priv(struct sdhci_host *host)
{
    return (void *)host->private;
}
////

/*****************************************************************************\
 * Device allocation/registration                                            *
\*****************************************************************************/

struct sdhci_host *sdhci_alloc_host(struct device *dev,
    size_t priv_size)
{
    struct mmc_host *mmc;
    struct sdhci_host *host;
    mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
    host = mmc_priv(mmc);
    host->mmc = mmc;
    return host;
}
///

static inline void *mmc_priv(struct mmc_host *host)
{
    return (void *)host->private;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


 
static struct sdhci_ops sdhci_s3c_ops = {
    .get_max_clock        = sdhci_s3c_get_max_clk,
    .get_timeout_clock    = sdhci_s3c_get_timeout_clk,
    .change_clock        = sdhci_s3c_change_clock,
    .set_ios        = sdhci_s3c_set_ios,
};
///////


 
struct sdhci_ops {
    int        (*enable_dma)(struct sdhci_host *host);
    unsigned int    (*get_max_clock)(struct sdhci_host *host);
    unsigned int    (*get_timeout_clock)(struct sdhci_host *host);

    void        (*change_clock)(struct sdhci_host *host,
                    unsigned int clock);

    void        (*set_ios)(struct sdhci_host *host,
                   struct mmc_ios *ios);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////















阅读(1969) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~