Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5482508
  • 博文数量: 579
  • 博客积分: 1548
  • 博客等级: 上尉
  • 技术积分: 16621
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-12 15:29
个人简介

http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/

文章分类

全部博文(579)

文章存档

2018年(18)

2015年(91)

2014年(159)

2013年(231)

2012年(80)

分类: 嵌入式

2013-01-06 09:43:44

PC操作系统:ubuntu 11.10

使用的开发板:am335x_evm

开发板使用的操作系统:linux 3.2


在新版本的内核中struct device 已经没有bus_id成员,取而代之的是通过dev_name和dev_set_name对设备的名字进行操作。

        dev_name和dev_set_name在2.6.35.6内核中的源代码如下:

        static inline const char *dev_name(const struct device *dev)
        {
                /* Use the init name until the kobject becomes available */
                if (dev->init_name)
                        return dev->init_name;

                return kobject_name(&dev->kobj);
        }

        extern int dev_set_name(struct device *dev, const char *name, ...)
                __attribute__((format(printf, 2, 3)));

kernel 邮件列表

中讲了:struct device - replace bus_id with dev_name(),以后只要使用dev->bus_id的时候,改成dev_name(dev)就可以了。


lddbus.h 文件不需要修改;

lddbus.c 文件有所修改。


#include
#include
#include
#include
#include

#include "ldd_bus.h"

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("SM");
static    char *version = "$revision : 2.0 $";

//respond to hotplug events

/*

struct kobj_uevent_env {
    char *envp[UEVENT_NUM_ENVP];
    int envp_idx;
    char buf[UEVENT_BUFFER_SIZE];
    int buflen;
};

*/
static    int        ldd_hotplug(struct device * dev,struct kobj_uevent_env *env)
{
    env->envp[0]    = env->buf;
    if(snprintf(env->buf,env->buflen,"LDDBUS_VERSION=%s",version) >= env->buflen)
        return -ENOMEM;

    env->envp[1]    = NULL;
    return 0;
}


//match ldd device to drivers
static    int        ldd_match(struct device *dev,struct device_driver *driver)
{
    return !strncmp(dev->init_name,driver->name,strlen(driver->name));
}


//ldd bus device
static    void    ldd_bus_release(struct device *dev)
{
    printk(KERN_NOTICE"lddbus release \n");
}


struct device ldd_bus =
{
    .init_name    = "lld0",
    .release    = ldd_bus_release,
};


//the bus type
struct bus_type ldd_bus_type =
{
    .name        = "ldd",
    .match        = ldd_match,
    .uevent        = ldd_hotplug,
};


//export a simple attribute
static    ssize_t    show_bus_version(struct bus_type *bus,char *buf)
{
    return snprintf(buf,PAGE_SIZE,"%s\n",version);
}

static    BUS_ATTR(version,S_IRUGO,show_bus_version,NULL);




//ldd devices
static    void    ldd_dev_release(struct device *dev)
{
    printk(KERN_NOTICE"ldddev release \n");
}


int        register_ldd_device(struct ldd_device *ldddev)
{
    ldddev->dev.bus        = &ldd_bus_type;
    ldddev->dev.parent    = &ldd_bus;
    ldddev->dev.release    = ldd_dev_release;

//struct device 中没有 bus_id 成员,应用过 init_name 替代
//    strncpy(ldddev->dev.bus_id,ldddev->name,BUS_ID_SIZE);
    dev_set_name(&ldddev->dev,ldddev->name);

    return device_register(&ldddev->dev);
}
EXPORT_SYMBOL(register_ldd_device);

void    unregister_ldd_device(struct ldd_device * ldddev)
{
    device_unregister(&ldddev->dev);
}
EXPORT_SYMBOL(unregister_ldd_device);



static    ssize_t    show_version(struct device_driver *driver,char *buf)
{
    struct    ldd_driver *ldriver    = to_ldd_driver(driver);

    sprintf(buf,"%s\n",ldriver->version);
    return strlen(buf);
}



int     register_ldd_driver(struct ldd_driver *driver)
{
    int        ret;
   
    driver->driver.bus    = &ldd_bus_type;
    ret    = driver_register(&driver->driver);
    if(ret)
        return ret;


/*

struct attribute {
    const char        *name;
    mode_t            mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
    struct lock_class_key    *key;
    struct lock_class_key    skey;
#endif
};

*/
    driver->version_attr.attr.name        = "version";

//struct attribute 中没有 owner 成员
//    driver->version_attr.attr.owner        = driver->module;
    driver->version_attr.attr.mode        = S_IRUGO;
    driver->version_attr.show            = show_version;

    return driver_create_file(&driver->driver,&driver->version_attr);
}
EXPORT_SYMBOL(register_ldd_driver);



void    unregister_ldd_driver(struct ldd_driver * driver)
{
    driver_unregister(&driver->driver);
}
EXPORT_SYMBOL(unregister_ldd_driver);




static    int        __init    ldd_bus_init(void)
{
    int        ret;

    ret        = bus_register(&ldd_bus_type);
    if(ret)
        return ret;

    if(bus_create_file(&ldd_bus_type,&bus_attr_version))
        printk(KERN_NOTICE"Unable to create version attribute\n");
   
    ret    = device_register(&ldd_bus);
    if(ret)
        printk(KERN_NOTICE"Unable  to register ldd0\n");

    printk(KERN_NOTICE"ldd bus init \n");

    return ret;
}


static    void            ldd_bus_exit(void)
{
    device_unregister(&ldd_bus);
    bus_unregister(&ldd_bus_type);   
    printk(KERN_NOTICE"ldd bus exit \n");
}

module_init(ldd_bus_init);
module_exit(ldd_bus_exit);



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