[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: alloc_chrdev_region/unregister_chrdev_region - Issue
Hello!
> >>>> /* 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
You should probably use another Linux source code lxr, lxr.oss.org.cn
is outdated and not working at the moment.
> >>>> > 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[].
AFAIU, chrdevs is an array of singly-linked lists
('struct char_device_struct' even has a 'next' entry). When unregistering
a char dev region, __unregister_chrdev_region deletes an entry from one
list. If that entry was the last entry in the list, the corresponding
chrdevs[i] becomes NULL.
REF: http://lxr.linux.no/linux+v2.6.27.9/fs/char_dev.c#L179
> >> 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.
Yes, unregister_chrdev_region's first argument is 'dev_t from', therefore
you should use 'cmod_dev_number'.
Alexander
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ