Linux内核大讲堂之设备驱动的基石驱动模型(7)

时间:2022-05-18 10:41:55

转自:无为和尚的Linux内核大讲堂系列。http://blog.csdn.net/z2007b/article/details/6388753

终于快讲完了,这一节其实就是让上节我们所说的四大天王露下小脸。源码分析请自行完成吧。我建议大家可以试着先看一下代码,如果能看懂,那就把我写的那破玩意删掉,自已实现一遍,如果不能看懂,那马上回过去从第一小节重新看过,耐心,一定要有耐心,没耐心,啥都完了。帖上原码:

Makefile:

obj-m+=wwhs_bus.o

KERNELDIR=/opt/kernel/linux-2.6.38/linux-2.6.38.5

PWD:=$(shell pwd)

all:

make -C $(KERNELDIR) M=$(PWD) modules

clean: 

rm -rf *.o* *.ko* *.mod.c *.cmd *.symvers .tmp_versions .*.cmd

wwhs_public.h:

#include <linux/module.h>

#include <linux/device.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/stat.h>

#include <linux/slab.h>

#include <linux/kobject.h>

#include <linux/klist.h>

#include <linux/kdev_t.h>

#include <linux/fs.h>

#include <linux/major.h>

#include <linux/kprobes.h>

#define wwhs_dbg(dbgbuf) printk(KERN_ERR"wwhs:%s/n",dbgbuf);

#include "../wwhs_public.h"

#define WWHS_MAJOR 83

void wwhs_release(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is release/n",dev->kobj.name);

}

struct device wwhs_bus = {

.init_name = "wwhs",

.release = wwhs_release,

};

static struct device wwhs_dev = {

.init_name = "wwhsled0",

.release = wwhs_release,

};

static int wwhs_bus_match(struct device *dev, struct device_driver *drv)

{

int ret = -1;

ret = strncmp(dev->kobj.name, drv->name, strlen(drv->name));

printk(KERN_ERR"wwhs:dev->kobj.name:%s drv->name:%s ret:%d/n",dev->kobj.name,drv->name,ret);

return !ret;

}

static int wwhs_bus_probe(struct device *dev)

{

int ret = -1;

if (dev->driver->probe)

ret = dev->driver->probe(dev);

return ret;

}

static struct bus_type wwhs_bus_type = {

.name = "wwhs",

.match = wwhs_bus_match,

};

static struct class *wwhs_class;

static int wwhs_bus_register()

{

int ret = -1;

wwhs_bus.class = wwhs_class;

ret = device_register(&wwhs_bus);

if (ret) goto device_error;

ret = bus_register(&wwhs_bus_type);

  if (ret) goto bus_error;

return ret;

bus_error:

device_unregister(&wwhs_bus);

device_error:

return ret;

}

static void wwhs_bus_unregister()

{

device_unregister(&wwhs_bus);

bus_unregister(&wwhs_bus_type);

}

static int wwhs_class_register(void)

{

wwhs_class = class_create(THIS_MODULE, "wwhsclass");

if (IS_ERR(wwhs_class)){

printk(KERN_ERR"wwhs: class create error/n");

return PTR_ERR(wwhs_class);

}

printk(KERN_ERR"wwhs: class create success/n");

return 0;

}

static void wwhs_class_unregister()

{

class_destroy(wwhs_class);

}

static int wwhs_device_register(struct device *dev)

{

dev->devt = MKDEV(WWHS_MAJOR,1);

dev->bus = &wwhs_bus_type;

dev->parent = &wwhs_bus;

return device_register(dev);

}

static void wwhs_device_unregister(struct device *wwhs_dev)

{

device_unregister(wwhs_dev);

}

static struct device_driver wwhs_drv = {

.name = "wwhsled",

};

static wwhs_drv_probe(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is probe/n",dev->kobj.name);

return 0;

}

static wwhs_drv_remove(struct device *dev)

{

printk(KERN_ERR"wwhs:dev:%s is remove/n",dev->kobj.name);

return 0;

}

static int wwhs_driver_register(struct device_driver *wwhs_driver)

{

int ret = -1;

wwhs_driver->bus = &wwhs_bus_type;

wwhs_driver->owner = THIS_MODULE;

wwhs_driver->probe = wwhs_drv_probe;

wwhs_driver->remove = wwhs_drv_remove;

ret = driver_register(wwhs_driver);

return ret;

}

static void wwhs_driver_unregister(struct device_driver *wwhs_driver)

{

driver_unregister(wwhs_driver);

}

static int __init wwhs_init()

{

int ret = -1;

ret = wwhs_class_register();

if (ret) goto error;

ret = wwhs_bus_register();

if (ret) goto error;

ret = wwhs_device_register(&wwhs_dev);

if (ret) goto bus_error;

ret = wwhs_driver_register(&wwhs_drv);

if (ret) goto device_error;

return ret;

device_error:

wwhs_device_unregister(&wwhs_dev);

bus_error:

wwhs_bus_unregister();

class_error:

wwhs_class_unregister();

error:

return ret;

}

static void __exit wwhs_exit()

{

wwhs_device_unregister(&wwhs_dev);

wwhs_driver_unregister(&wwhs_drv);

wwhs_bus_unregister();

wwhs_class_unregister();

}

module_init(wwhs_init);

module_exit(wwhs_exit);

MODULE_AUTHOR("wwhs");

MODULE_DESCRIPTION("wwhs_bus test");

MODULE_LICENSE("GPL");

上面就是四大天王小露一下脸,至此,驱动模型的分析要告一段落了。如果根着看了的朋友,我相信肯定是有所收获的。谢谢各位。你们的支持是我前进的动力。^_^