linux2.6.28块设备mmc_sd卡结构体框架

图片


图片

//

本结构表述一张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);

};

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xx-xx-xxx-xxx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值