[S390] dasd: fix bug in dasd initialization cleanup
The initialization of the dasd_eer code is one of the last steps of the dasd driver initialization. When initialization fails in one of the earlier steps, the dasd_exit function is called to clean up what has been done so far. So the dasd_eer_exit function may be called, although the dasd_eer_init function wasn't called before and dasd_eer_exit tries to unregister a misc device that wasn't registered, which results in a BUG. Make sure that dasd_eer_exit can be called without initialization. Use a dynamically allocated struct miscdevice instead of a static one, so we only try to unregister the device if it exists and was actually registered. Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
dbd8ae6306
commit
e3c699b38e
@@ -658,18 +658,24 @@ static struct file_operations dasd_eer_fops = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct miscdevice dasd_eer_dev = {
|
static struct miscdevice *dasd_eer_dev = NULL;
|
||||||
.minor = MISC_DYNAMIC_MINOR,
|
|
||||||
.name = "dasd_eer",
|
|
||||||
.fops = &dasd_eer_fops,
|
|
||||||
};
|
|
||||||
|
|
||||||
int __init dasd_eer_init(void)
|
int __init dasd_eer_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = misc_register(&dasd_eer_dev);
|
dasd_eer_dev = kzalloc(sizeof(*dasd_eer_dev), GFP_KERNEL);
|
||||||
|
if (!dasd_eer_dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
dasd_eer_dev->minor = MISC_DYNAMIC_MINOR;
|
||||||
|
dasd_eer_dev->name = "dasd_eer";
|
||||||
|
dasd_eer_dev->fops = &dasd_eer_fops;
|
||||||
|
|
||||||
|
rc = misc_register(dasd_eer_dev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
kfree(dasd_eer_dev);
|
||||||
|
dasd_eer_dev = NULL;
|
||||||
MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
|
MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
|
||||||
"register misc device");
|
"register misc device");
|
||||||
return rc;
|
return rc;
|
||||||
@@ -680,5 +686,9 @@ int __init dasd_eer_init(void)
|
|||||||
|
|
||||||
void dasd_eer_exit(void)
|
void dasd_eer_exit(void)
|
||||||
{
|
{
|
||||||
WARN_ON(misc_deregister(&dasd_eer_dev) != 0);
|
if (dasd_eer_dev) {
|
||||||
|
WARN_ON(misc_deregister(dasd_eer_dev) != 0);
|
||||||
|
kfree(dasd_eer_dev);
|
||||||
|
dasd_eer_dev = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user