LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2014|回复: 4

register_chrdev_region的问题

[复制链接]
发表于 2007-10-10 12:30:44 | 显示全部楼层 |阅读模式
2.6.21.5内核中register_chrdev_region的源代码如下:

int register_chrdev_region(dev_t from, unsigned count, const char *name)
{
        struct char_device_struct *cd;
        dev_t to = from + count;
        dev_t n, next;

        for (n = from; n < to; n = next) {
                next = MKDEV(MAJOR(n)+1, 0);
                if (next > to)
                        next = to;
                cd = __register_chrdev_region(MAJOR(n), MINOR(n),
                               next - n, name);
                if (IS_ERR(cd))
                        goto fail;
        }

        return 0;

fail:
        to = n;

        for (n = from; n < to; n = next) {
                next = MKDEV(MAJOR(n)+1, 0);
                kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
        }

        return PTR_ERR(cd);
}

     关键是对其中变量to的赋值表示质疑。from与to都是dev_t类型的,那么高12位表示主设备号,低20位表示次设备号。
   在对to赋值时,直接是from + count;而在for循环体内,next每次又是主设备号加1,那么这样,一般情况下,当count在比较小的范围内,不管count是多少,for循环只能执行一次。
   不知道为什么这样写?
发表于 2007-10-11 06:40:38 | 显示全部楼层
your understanding for the code is right.   I want to know  why,too.
回复 支持 反对

使用道具 举报

发表于 2007-10-11 06:47:55 | 显示全部楼层
register_chrdev_region  包装了__register_chrdev_region 函数,适应
coun <= 2的20次方   和  count > 2的20次方 的这两种情况  ,

实际上for (n = from; n < to; n = next) ,此 循环的次数 =  count / 2的20次方+1


不知是否正确?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-10-12 18:45:19 | 显示全部楼层
写了个小程序测试了一下,  当count < 1048576时, for循环只执行一次, 并且分别
1048576 - MINOR(n)个设备.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>

MODULE_LICENSE("Dual BSD/GPL");

static int howmany = 1;
static char* whom = "world";

module_param(howmany, int, S_IRUGO);
module_param(whom, charp, S_IRUGO);


void register_chrdev_region_test(dev_t from, unsigned count)
{
        dev_t to = from + count;
        dev_t n, next;
        int i;

        i = 1;

        printk(KERN_ALERT"from = %d, count = %d, to = %d\n", from, count, to);

        for (n = from; n < to; n = next)
        {
                next = MKDEV(MAJOR(n)+1, 0);
                printk(KERN_ALERT"next = %d , i = %d, next -n = %d,  ", next, i, next - n);
                if (next > to)
                {
                        next = to;
                        printk(KERN_ALERT"next > to is true\n");
                }

                i++;               
        }
}

static int __init hello_init(void)
{
        int i;
        printk(KERN_ALERT"Hello, world, howmany = %d, whom = %s\n", howmany, whom);

        for (i=0; i<howmany; i++)
                printk(KERN_ALERT"Hello, %s, i = %d\n", whom, i);
                /*printk(KERN_INFO"Hello, %s, i = %d\n", whom, i);*/

        printk(KERN_ALERT"Hello, world2, howmany = %d, whom = %s\n", howmany, whom);

        i = MKDEV(1, 1);
        printk(KERN_ALERT"dev_t i = %d\n", i);

        i = MKDEV(5, 3);
        register_chrdev_region_test(i, 12);

        printk(KERN_ALERT"register again.\n");
        register_chrdev_region_test(i, 122);

        return 0;
}

static void __exit hello_exit(void)
{
        printk(KERN_ALERT"Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);
回复 支持 反对

使用道具 举报

发表于 2007-10-13 07:32:39 | 显示全部楼层
此 循环的次数 = count / 2的20次方+1  

看来我的分析正确。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表