Example #1
0
File: main.c Project: matrix207/ldd
int scull_init_module(void)
{
	int result, i;
	dev_t dev = 0;

/*
 * Get a range of minor numbers to work with, asking for a dynamic
 * major unless directed otherwise at load time.
 */
	if (scull_major) {
		dev = MKDEV(scull_major, scull_minor);
		result = register_chrdev_region(dev, scull_nr_devs, "scull");
	} else {
		result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
				"scull");
		scull_major = MAJOR(dev);
	}
	if (result < 0) {
		printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
		return result;
	}

        /* 
	 * allocate the devices -- we can't have them static, as the number
	 * can be specified at load time
	 */
	scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
	if (!scull_devices) {
		result = -ENOMEM;
		goto fail;  /* Make this more graceful */
	}
	memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));

        /* Initialize each device. */
	for (i = 0; i < scull_nr_devs; i++) {
		scull_devices[i].quantum = scull_quantum;
		scull_devices[i].qset = scull_qset;
		#ifndef init_MUTE
		sema_init(&scull_devices[i].sem, 1);
		#else
		init_MUTEX(&scull_devices[i].sem);
		#endif
		scull_setup_cdev(&scull_devices[i], i);
	}

        /* At this point call the init function for any friend device */
	dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
	dev += scull_p_init(dev);
	dev += scull_access_init(dev);

#ifdef SCULL_DEBUG /* only when debugging */
	scull_create_proc();
#endif

	return 0; /* succeed */

  fail:
	scull_cleanup_module();
	return result;
}
Example #2
0
int init_module(void)
{
    int result, i;

    /*
     * Register your major, and accept a dynamic number
     */
    result = register_chrdev(scull_major, "scull", &scull_fops);
    if (result < 0) {
        printk(KERN_WARNING "scull: can't get major %d\n",scull_major);
        return result;
    }
    if (scull_major == 0) scull_major = result; /* dynamic */

    /* 
     * allocate the devices -- we can't have them static, as the number
     * can be specified at load time
     */
    scull_devices = kmalloc(scull_nr_devs * sizeof (Scull_Dev), GFP_KERNEL);
    if (!scull_devices) {
        result = -ENOMEM;
        goto fail_malloc;
    }
    memset(scull_devices, 0, scull_nr_devs * sizeof (Scull_Dev));
    for (i=0; i < scull_nr_devs; i++) {
        scull_devices[i].quantum = scull_quantum;
        scull_devices[i].qset = scull_qset;
    }

    /* At this point call the init function for any friend device */
    if ( (result = scull_p_init()) )
        goto fail_pipe;
    if ( (result = scull_access_init()) )
        goto fail_access;
    /* ... */

#ifndef SCULL_DEBUG
    REGISTER_SYMTAB(NULL); /* otherwise, leave global symbols visible */
#endif

#ifdef SCULL_USE_PROC /* only when available */
    /* this is the last line in init_module */
    proc_register_dynamic(&proc_root, &scull_proc_entry);
#endif

    return 0; /* succeed */

  fail_access: scull_p_cleanup();
  fail_pipe:   kfree(scull_devices);
  fail_malloc: unregister_chrdev(scull_major, "scull");
    return result;
}
Example #3
0
int scull_init_module(void)
{
    int result, i;

#ifdef CONFIG_DEVFS_FS
    /* If we have devfs, create /dev/scull to put files in there */
    scull_devfs_dir = devfs_mk_dir(NULL, "scull", NULL);
    if (!scull_devfs_dir) return -EBUSY; /* problem */

#else /* no devfs, do it the "classic" way  */    

    /*
     * Register your major, and accept a dynamic number. This is the
     * first thing to do, in order to avoid releasing other module's
     * fops in scull_cleanup_module()
     */
    result = register_chrdev(scull_major, "scull", &scull_fops);
    if (result < 0) {
        printk(KERN_WARNING "scull: can't get major %d\n",scull_major);
        return result;
    }
    if (scull_major == 0) scull_major = result; /* dynamic */

#endif /* CONFIG_DEVFS_FS */
    /* 
     * allocate the devices -- we can't have them static, as the number
     * can be specified at load time
     */
    scull_devices = kmalloc(scull_nr_devs * sizeof(Scull_Dev), GFP_KERNEL);
    if (!scull_devices) {
        result = -ENOMEM;
        goto fail;
    }
    memset(scull_devices, 0, scull_nr_devs * sizeof(Scull_Dev));
    for (i=0; i < scull_nr_devs; i++) {
        scull_devices[i].quantum = scull_quantum;
        scull_devices[i].qset = scull_qset;
        sema_init(&scull_devices[i].sem, 1);
#ifdef CONFIG_DEVFS_FS
        sprintf(devname, "%i", i);
        devfs_register(scull_devfs_dir, devname,
                       DEVFS_FL_AUTO_DEVNUM,
                       0, 0, S_IFCHR | S_IRUGO | S_IWUGO,
                       &scull_fops,
                       scull_devices+i);
#endif  
    }

    /* At this point call the init function for any friend device */
    if ( (result = scull_p_init()) )
        goto fail;
    if ( (result = scull_access_init()) )
        goto fail;
    /* ... */

#ifndef SCULL_DEBUG
    EXPORT_NO_SYMBOLS; /* otherwise, leave global symbols visible */
#endif

#ifdef SCULL_DEBUG /* only when debugging */
    scull_create_proc();
#endif

    return 0; /* succeed */

  fail:
    scull_cleanup_module();
    return result;
}
Example #4
0
int scull_init_module(void)
{
	int result, i;
	dev_t dev = 0;

/*
 * Get a range of minor numbers to work with, asking for a dynamic
 * major unless directed otherwise at load time.
 * 根据scull_major的值是否为0,分别采用静态分配或动态分配
 * scull_major为主设备编号,在scull中初始定义为 #define SCULL_MAJOR 0,如果用户通过命令行参数给major赋 >0 的值,则采取静态分配
 * scull_minor为从设备编号
 */
    printk(KERN_ALERT "Debug by andrea:scull_init_module()/n");
	if (scull_major) {
		dev = MKDEV(scull_major, scull_minor);
		/*
		 * 静态分配设备编号
		*/
		result = register_chrdev_region(dev, scull_nr_devs, "scull");
	} else {
		/*
		 * 动态分配设备编号
		 */
		result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
				"scull");
		scull_major = MAJOR(dev);
	}

	/*分配设备编号出错*/
	if (result < 0) {
		printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
		return result;
	}

    /* 
	 * allocate the devices -- we can't have them static, as the number
	 * can be specified at load time
	 */
	/*
	 * 为每一个设备分配内存空间
	 * scull_nr_devs 默认为4 ,即默认创建4个scull设备, 在scull.h 定义 define SCULL_NR_DEVS 4 
	 */
	scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
	if (!scull_devices) {
		result = -ENOMEM;
		goto fail;  /* Make this more graceful */
	}
	/*
	 * 将scull_devices分配的内存清零
	 */
	memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));

    /* Initialize each device. */
    /*
     * 初始化 scull_nr_dev个 scull_dev结构体, 即scull_nr_dev个scull_dev设备
     * scull_devices[i].qset代表当前scull设备中每一个qset的data域指向的数组有SCULL_QSET(默认1000)个指针
     * scull_devices[i].quantum代表当前scull设备中每一个qset中上面的数组指向的量子有SCULL_QUANTUM(默认4000)个字节
     */
	for (i = 0; i < scull_nr_devs; i++) {
		scull_devices[i].quantum = scull_quantum;
		scull_devices[i].qset = scull_qset;
		/* init_MUTEX(&scull_devices[i].sem);*/
        sema_init(&scull_devices[i].sem,1);
		/*
		 * 调用了scull_setup_cdev函数对相应scull设备进行设置
		 */
		scull_setup_cdev(&scull_devices[i], i);
	}

    /* At this point call the init function for any friend device */
	dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
	dev += scull_p_init(dev);
	dev += scull_access_init(dev);

#ifdef SCULL_DEBUG /* only when debugging */
	scull_create_proc();
#endif

	return 0; /* succeed */

  fail:
	scull_cleanup_module();
	return result;
}
Example #5
0
/*[Tag000]
 * 当模块加载时,调用;但是为什么要放在最后来实现他呢,看到Tag002时,你应该就明白了;
*/
int scull_init_module(void)
{
	int result, i;
	dev_t dev = 0;

/* [Tag001] */
/* [1]分配设备编号 */
/*
 * Get a range of minor numbers to work with, asking for a dynamic
 * major unless directed otherwise at load time.
 */
	if (scull_major) { 	/* 预先自己指定了主设备号 */
		dev = MKDEV(scull_major, scull_minor); /* 利用主设备号,找到设备编号给方法1用 */
		result = register_chrdev_region(dev, scull_nr_devs, "scull");
	} else {		/* 动态自己生成设备编号,然后再利用设备编号得到主设备号;
						记住如果用这个方法那么就要后建设备文件了,因为不能提前知道主号
						当然也可以利用ldd3书中提供的脚本,巨方便&&通用 */
		result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
				"scull");
		scull_major = MAJOR(dev);
	}
	if (result < 0) {
		printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
		return result;
	}

    /*[2]设备对象实例化*/ 
        /* 
	 * allocate the devices -- we can't have them static, as the number
	 * can be specified at load time
	 */
	scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
	if (!scull_devices) {
		result = -ENOMEM;
		goto fail;  /* Make this more graceful */
	}
	memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));

/* [3]在这里初始化设备用了2.6的新方法,在scull_setup_cdev里完成 */
        /* Initialize each device. */
	for (i = 0; i < scull_nr_devs; i++) {
		scull_devices[i].quantum = scull_quantum;	/* 可以根据自己insmod时传参
														来自己改变量子和量子集(指针数组)的大小 */
		scull_devices[i].qset = scull_qset;
		init_MUTEX(&scull_devices[i].sem);
		scull_setup_cdev(&scull_devices[i], i);	/* 在分别完主设备编号后goto Tag002 设备注册 */
	}

        /* At this point call the init function for any friend device */
	dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
	dev += scull_p_init(dev);
	dev += scull_access_init(dev);

#ifdef SCULL_DEBUG /* only when debugging */
	scull_create_proc();
#endif

	return 0; /* succeed */

  fail:
	scull_cleanup_module();
	return result;
}