diff options
Diffstat (limited to 'driver/aim-cdev/cdev.c')
-rw-r--r-- | driver/aim-cdev/cdev.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/driver/aim-cdev/cdev.c b/driver/aim-cdev/cdev.c index 7f51024..ce0f9fc 100644 --- a/driver/aim-cdev/cdev.c +++ b/driver/aim-cdev/cdev.c @@ -99,11 +99,16 @@ static void destroy_cdev(struct aim_channel *c) device_destroy(aim_class, c->devno); cdev_del(&c->cdev); - kfifo_free(&c->fifo); spin_lock_irqsave(&ch_list_lock, flags); list_del(&c->list); spin_unlock_irqrestore(&ch_list_lock, flags); +} + +static void destroy_channel(struct aim_channel *c) +{ ida_simple_remove(&minor_id, MINOR(c->devno)); + kfifo_free(&c->fifo); + kfree(c); } /** @@ -170,9 +175,8 @@ static int aim_close(struct inode *inode, struct file *filp) stop_channel(c); mutex_unlock(&c->io_mutex); } else { - destroy_cdev(c); mutex_unlock(&c->io_mutex); - kfree(c); + destroy_channel(c); } return 0; } @@ -242,7 +246,7 @@ static ssize_t aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { size_t to_copy, not_copied, copied; - struct mbo *mbo; + struct mbo *mbo = NULL; struct aim_channel *c = filp->private_data; mutex_lock(&c->io_mutex); @@ -337,14 +341,14 @@ static int aim_disconnect_channel(struct most_interface *iface, int channel_id) spin_lock(&c->unlink); c->dev = NULL; spin_unlock(&c->unlink); + destroy_cdev(c); if (c->access_ref) { stop_channel(c); wake_up_interruptible(&c->wq); mutex_unlock(&c->io_mutex); } else { - destroy_cdev(c); mutex_unlock(&c->io_mutex); - kfree(c); + destroy_channel(c); } return 0; } @@ -546,7 +550,7 @@ static void __exit mod_exit(void) list_for_each_entry_safe(c, tmp, &channel_list, list) { destroy_cdev(c); - kfree(c); + destroy_channel(c); } class_destroy(aim_class); unregister_chrdev_region(aim_devno, 1); |