有关linux设备模型这一块比较复杂,我不敢断定自己理解的肯定正确,但是我会在做这个驱动的过程中回过头来修改自己的笔记并且纠正自己在blog上贴的并不正确的地方。另外,我的无线网卡是挂接在SDIO总线上的,所以呢,我们之前会先介绍一点SDIO的驱动,当然并不在这篇blog上,这篇blog会是总领性的关于基础知识的介绍。下面是笔记:
在进入正式的驱动代码之前,我们不得不补充一点基础知识,也就是在2.6版本内核的现在,内核是如何管理总线,驱动,设备之间的关系的,关于bus_type、device_driver、device这三个内核结构在内核代码中可以找到。由于这三个结构的重要性,我们在这里先将它们贴出来,我会用红色的注释标注。我在笔记中将会提到的一些结构成员以其代表的意义,这样便于对照。(我不得不承认,这三个结构的代码枯燥复杂,但我可以保证,在看完我总结的笔记之后,你会对这三个结构中重要的数据成员有个非常不错的了解,当然你得对内核和驱动有基本的了解。如果我误导了你,请指正我,所以我的建议是不妨先看完了笔记再来看这些结构)
1、设备结构的定义:
struct device {
struct klist klist_children;
struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *parent;
struct kobject kobj; //kobject结构,关于这个结构与kset结构以及subsystem结构,笔记中会有描述。
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_type *type;
unsigned is_registered:1;
unsigned uevent_suppress:1;
struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
*/
struct bus_type * bus; /* type of bus device is on */ //这个设备挂接的总线的类型
struct device_driver *driver; /* which driver has allocated this device */ //这个设备挂接的驱动
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device core doesn't touch it */
struct dev_pm_info power;
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
struct list_head dma_pools; /* dma pools (if dma'ble) */
struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */
/* arch specific additions */
struct dev_archdata archdata;
spinlock_t devres_lock;
struct list_head devres_head;
/* class_device migration path */
struct list_head node;
struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */
void (*release)(struct device * dev);
};
2、设备驱动的结构:
struct device_driver {
const char * name; &n
[3]sdio架构初解
来源: 互联网 发布时间: 2013-11-07
SDIO架构初解
谨以此文纪念过往的岁月
一.前言
SD卡的大名是耳熟能详,但是SDIO总线确是不为人解,不过说起他的近亲SPI就知道了。我们这里主要是理解SDIO总线,并不去理解SPI总线。也许大家会畏惧其庞大的代码,其实我们并不需要详细理解其具体的实现,我们需要理解其架构。
二.主机(host)
在linux2.6.28中,在sdhci-s3c.c实现对主机的sdhci的驱动,而其设备的添加则在smdk6410_devices中。
在sdhci-s3c.c的sdhci_s3c_probe实现对主机端的驱,对于里面具体的一些实现我们就不看了,主要是看其中通用的code。
static int __devinit sdhci_s3c_probe(structplatform_device *pdev)
{
structsdhci_host*host;
structsdhci_s3c *sc;
host= sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
sc= sdhci_priv(host);
sdhci_add_host(host);
}
对于上面的函数,主要就是关心上面的几段代码。首先,来看sdhci_host这个结构体,这个是个很重要的东西,这个将会贯穿整个驱动。
struct sdhci_host {
/*Data set by hardware interface driver */
constchar *hw_name; /* Hardware bus name */
unsignedint quirks; /* Deviations from spec. */
int irq; /* Device IRQ */
void__iomem * ioaddr; /* Mapped address */
conststruct sdhci_ops *ops; /* Low level hw interface */
structmmc_host *mmc; /* MMC structure */
u64 dma_mask; /* custom DMA mask */
spinlock_t lock; /* Mutex */
int flags; /* Host attributes */
unsignedint version; /* SDHCI spec. version */
unsignedint max_clk; /* Max possible freq (MHz) */
unsignedint timeout_clk; /* Timeout freq (KHz) */
unsignedint clock; /* Current clock (MHz) */
unsignedshort power; /* Current voltage */
structmmc_request *mrq; /* Current request */
structmmc_command *cmd; /* Current command */
structmmc_data *data; /* Current data request */
unsignedint data_early:1; /* Data finished before cmd */
structsg_mapping_iter sg_miter; /* SG state for PIO */
unsignedint &nb