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