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; //init_MUTEX(&scull_devices[i].sem); //mutex_init(&scull_devices[i].sem); sema_init(&scull_devices[i].sem,1); 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(); printk(KERN_ALERT "Debugging is working"); #endif printk(KERN_ALERT "Scull device registered.. \n"); return 0; /* succeed */ fail: scull_cleanup_module(); return result; }
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; //init_MUTEX(&scull_devices[i].sem); //changed to below based on this: http://www.linuxquestions.org/questions/blog/frandalla-68463/patching-802-11-linux-sta-driver-for-kernel-2-6-37-3558/ sema_init(&scull_devices[i].sem,1); 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; }
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. This must be dynamic as the device 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; } 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; mutex_init(&scull_devices[i].mutex); scull_setup_cdev(&scull_devices[i], i); } /* 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; }
static int __init scull_init_module( void ) { int ret, i; dev_t devno = 0; if ( scull_major ) { devno = MKDEV( scull_major, scull_mino ); ret = register_chrdev_region( devno, 1, "scull" ); }else{ ret = alloc_chrdev_region( &devno, scull_mino, 1, "scull" ); scull_major = MAJOR( devno ); } if ( ret < 0 ) { printk( KERN_WARNING "scull: can't get major %d\n", scull_major ); return(ret); } scull_devices = kmalloc( sizeof(struct scull_dev) * scull_nr_dev, GFP_KERNEL ); if ( !scull_devices ) { ret = -ENOMEM; goto fail; } for ( i = 0; i < scull_nr_dev; i++ ) { scull_devices[i].quantum = SCULL_QUANTUM; scull_devices[i].qset = SCULL_QSET; sema_init( &scull_devices[i].sem, 1 ); scull_setup_dev( &scull_devices[i], i ); } PDEBUG( "device open\n" ); /* * if(printk_ratelimit()) * PDEBUG("device open\n"); */ /* * print_dev_t(buffer, dev); * format_dev_t(buffer, dev) */ #ifdef SCULL_DEBUG scull_create_proc(); #endif return(0); fail: scull_cleanup_module(); return(ret); }
int scull_init_module(void) { int result, i; dev_t dev = 0; 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"); //alloc_chrdev_region 第二个参数?? scull_major = MAJOR(dev); } if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n", scull_major); return result; } scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; //??-ENOMEM goto fail; } memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev)); for (i = 0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; //scull_qset?? init_MUTEX(&scull_devices[i].sem); //??init_MUTEX 加锁 scull_setup_cdev(&scull_devices[i], i); } // dev = MKDEV(scull_major, scull_minor + scull_nr_devs); // dev += scull_p_init(dev);// // dev += scull_access_init(dev); //#ifdef SCULL_DEBUG scull_create_proc(); //#endif return 0; fail: scull_cleanup_module(); return result; }
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; }
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; }
/*[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; }