From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Christian Gromm Subject: [PATCH 10/13] staging: most: destroy cdev by channel disconnect Date: Fri, 31 Mar 2017 15:22:31 +0200 Message-ID: <20170331132234.21722-10-christian.gromm@microchip.com> In-Reply-To: <20170331132234.21722-1-christian.gromm@microchip.com> References: <20170331132234.21722-1-christian.gromm@microchip.com> MIME-Version: 1.0 Content-Type: text/plain List-ID: To: gregkh@linuxfoundation.org Cc: driverdev-devel@linuxdriverproject.org, Andrey Shvetsov , Christian Gromm From: Andrey Shvetsov Currently, when the channel disappears whereas the character device is open by an application, the character device will be destroyed only after the application closes the character device. When the channel appears again before the application closes the channel, the channel cannot be linked to the character device with the same name. This patch changes the described behavior and destroys the character device by the disconnecting the channel from the AIM. Signed-off-by: Andrey Shvetsov Signed-off-by: Christian Gromm --- drivers/staging/most/aim-cdev/cdev.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index 7f51024dc5eb..1e5cbc893496 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/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; } @@ -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); -- 2.11.0