I meant at BOOT time. On Sat, Dec 13, 2008 at 4:13 PM, Sandeep K Sinha <sandeepksinha@xxxxxxxxx> wrote: > May be at time itself the kernel confirms all the registered devices > and assign NULL to all remaining. > Not sure, but will figure that out from the code for sure. > > On Sat, Dec 13, 2008 at 1:32 PM, Chetan Nanda <chetannanda@xxxxxxxxx> wrote: >> >> >> On Tue, Dec 9, 2008 at 11:34 AM, Chetan Nanda <chetannanda@xxxxxxxxx> wrote: >>> >>> >>> On Mon, Dec 8, 2008 at 9:35 PM, Sandeep K Sinha <sandeepksinha@xxxxxxxxx> >>> wrote: >>>> >>>> On Mon, Dec 8, 2008 at 7:45 PM, Chetan Nanda <chetannanda@xxxxxxxxx> >>>> wrote: >>>> > Hi, >>>> > >>>> > I am using 'alloc_chrdev_region' for registering char device range and >>>> > then >>>> > 'unregister_chrdev_region' for un-registering it. >>>> > But on each insmod I am getting MAJOR number as one less then that of >>>> > previous time. >>>> >>>> /* temporary */ >>>> 96 if (major == 0) { >>>> 97 for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) { >>>> 98 if (chrdevs[i] == NULL) >>>> 99 break; >>>> 100 } >>>> 101 >>>> 102 if (i == 0) { >>>> 103 ret = -EBUSY; >>>> 104 goto out; >>>> 105 } >>>> 106 major = i; >>>> 107 ret = major; >>>> 108 } >>>> 109 >>>> >>>> REF: http://lxr.oss.org.cn/source/fs/char_dev.c#L80 >>>> > >>>> > On seeing the code (unregister_chrdev_region) it seems that it just >>>> > kfree >>>> > the chrdevs[] entry but not set it to NULL which cause for new >>>> > entry in chrdevs[]. >>>> > >>>> >>>> Thats right, it is like that. >>>> Dont have much idea regarding the same. I think we should assign a >>>> NULL to it for sure. >>> >>> I have tried with setting chrdevs entry to NULL after kfree but it didn't >>> help >>> >>> void unregister_chrdev_region(dev_t from, unsigned count) >>> { >>> 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; >>> kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n)); >>> } >>> /*I do it*/ >>> chrdevs[MAJOR(n)] = NULL; //<--- setting it to null here >>> } >>> >>> It seems that problem is in my test driver implementation. >>> Here are my init and clean-up function: >>> >>> int __init >>> cmos_init(void) >>> { >>> int i; >>> >>> /*Clear cmosdev_array struct*/ >>> memset((void *)&cmosdev_array, 0 , sizeof(struct cmos_dev*) * >>> NUM_CMOS_BANKS); >>> >>> /* Request dynamic allocation of a device major number */ >>> if (alloc_chrdev_region(&cmos_dev_number, 0, NUM_CMOS_BANKS, >>> DEVICE_NAME) < 0) >>> { >>> printk(KERN_DEBUG "Can't register device\n"); return -1; >>> } >>> >>> /* Populate sysfs entries */ >>> cmos_class = class_create(THIS_MODULE, DEVICE_NAME); >>> >>> for (i=0; i<NUM_CMOS_BANKS; i++) >>> { >>> /* Allocate memory for the per-device structure */ >>> cmos_devp = kmalloc(sizeof(struct cmos_dev), GFP_KERNEL); >>> if (!cmos_devp) >>> { >>> printk("Bad Kmalloc\n"); return 1; >>> } >>> cmosdev_array[i] = cmos_devp; >>> >>> /* Request I/O region */ >>> sprintf(cmos_devp->name, "cmos%d", i); >>> if (!(request_region(addrports[i], 2, cmos_devp->name))) >>> { >>> printk("cmos: I/O port 0x%x is not free.\n", addrports[i]); >>> return -EIO; >>> } >>> >>> /* Fill in the bank number to correlate this device >>> * with the corresponding CMOS bank */ >>> cmos_devp->bank_number = i; >>> >>> /* Connect the file operations with the cdev */ >>> cdev_init(&cmos_devp->cdev, &cmos_fops); >>> cmos_devp->cdev.owner = THIS_MODULE; >>> >>> /* Connect the major/minor number to the cdev */ >>> if(cdev_add(&cmos_devp->cdev,(cmos_dev_number + i),1)) >>> { >>> printk("Bad cdev\n"); >>> return 1; >>> } >>> >>> /* Send uevents to udev, so it'll create /dev nodes */ >>> class_device_create(cmos_class, NULL, (cmos_dev_number + i),NULL, >>> "cmos%d", i); >>> } >>> printk("CMOS Driver Initialized.\n"); >>> return 0; >>> } >>> >>> //clean-up function >>> /* Driver Exit */ >>> void __exit >>> cmos_cleanup(void) >>> { >>> int i; >>> >>> /* Release the major number */ >>> unregister_chrdev_region(MAJOR(cmos_dev_number), NUM_CMOS_BANKS); >>> >>> /* Release I/O region */ >>> for (i=0; i<NUM_CMOS_BANKS; i++) >>> { >>> /* Remove the cdev */ >>> cdev_del(&(cmosdev_array[i]->cdev)); >>> class_device_destroy(cmos_class, MKDEV(MAJOR(cmos_dev_number), >>> i)); >>> release_region(addrports[i], 2); >>> kfree(cmosdev_array[i]); >>> } >>> >>> /* Destroy cmos_class */ >>> class_destroy(cmos_class); >>> return; >>> } >>> >>> Please provide me any feedback on this piece of code. >> >> This issue is resolved, problem is indeed in my driver cleanup function. >> unregister_chrdev_region( >> MAJOR(cmos_dev_number), NUM_CMOS_BANKS); >> Instead of passing MAJOR(cmos_dev_number) passing 'cmod_dev_number' works. >> >> But still i an not able to figure out that how chrdevs[i] (in fs/char_dev.c) >> is getting NULL in unregister_chrdev_region >>> >>> >>>> >>>> > Thanks, >>>> > Chetan Nanda >>>> > >>>> >>>> >>>> >>>> -- >>>> Regards, >>>> Sandeep. >>>> >>>> >>>> >>>> >>>> >>>> >>>> "To learn is to change. Education is a process that changes the learner." >>> >> >> > > > > -- > Regards, > Sandeep. > > > > > > > "To learn is to change. Education is a process that changes the learner." > -- Regards, Sandeep. "To learn is to change. Education is a process that changes the learner." -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ