linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: linux-input@vger.kernel.org
Cc: Thomas Tuttle <ttuttle@chromium.org>
Subject: [PATCH 7/9] Input: serio_raw - explicitly mark disconnected ports as dead
Date: Wed,  5 Oct 2011 22:08:14 -0700	[thread overview]
Message-ID: <1317877696-7719-7-git-send-email-dmitry.torokhov@gmail.com> (raw)
In-Reply-To: <1317877696-7719-1-git-send-email-dmitry.torokhov@gmail.com>

Instead of relying on setting serio_raw->serio to NULL upon disconnecting
ports mark them explicitly as "dead". Also take and carry reference to
underlying serio port to make sure it does not go away until we are done
with it.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
 drivers/input/serio/serio_raw.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 64fcefb..30ff963 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -40,6 +40,7 @@ struct serio_raw {
 	wait_queue_head_t wait;
 	struct list_head client_list;
 	struct list_head node;
+	bool dead;
 };
 
 struct serio_raw_client {
@@ -91,7 +92,7 @@ static int serio_raw_open(struct inode *inode, struct file *file)
 		goto out;
 	}
 
-	if (!serio_raw->serio) {
+	if (serio_raw->dead) {
 		retval = -ENODEV;
 		goto out;
 	}
@@ -123,6 +124,8 @@ static void serio_raw_cleanup(struct kref *kref)
 
 	misc_deregister(&serio_raw->dev);
 	list_del_init(&serio_raw->node);
+
+	put_device(&serio_raw->serio->dev);
 	kfree(serio_raw);
 }
 
@@ -164,19 +167,18 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
 	char uninitialized_var(c);
 	ssize_t retval = 0;
 
-	if (!serio_raw->serio)
+	if (serio_raw->dead)
 		return -ENODEV;
 
 	if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	retval = wait_event_interruptible(serio_raw->wait,
-					  serio_raw->head != serio_raw->tail ||
-						!serio_raw->serio);
+			serio_raw->head != serio_raw->tail || serio_raw->dead);
 	if (retval)
 		return retval;
 
-	if (!serio_raw->serio)
+	if (serio_raw->dead)
 		return -ENODEV;
 
 	while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
@@ -201,7 +203,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
 	if (retval)
 		return retval;
 
-	if (!serio_raw->serio) {
+	if (serio_raw->dead) {
 		retval = -ENODEV;
 		goto out;
 	}
@@ -291,10 +293,12 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
 	snprintf(serio_raw->name, sizeof(serio_raw->name),
 		 "serio_raw%d", serio_raw_no++);
 	kref_init(&serio_raw->kref);
-	serio_raw->serio = serio;
 	INIT_LIST_HEAD(&serio_raw->client_list);
 	init_waitqueue_head(&serio_raw->wait);
 
+	serio_raw->serio = serio;
+	get_device(&serio->dev);
+
 	serio_set_drvdata(serio, serio_raw);
 
 	err = serio_open(serio, drv);
@@ -330,6 +334,7 @@ out_close:
 	list_del_init(&serio_raw->node);
 out_free:
 	serio_set_drvdata(serio, NULL);
+	put_device(&serio->dev);
 	kfree(serio_raw);
 out:
 	mutex_unlock(&serio_raw_mutex);
@@ -365,7 +370,7 @@ static void serio_raw_disconnect(struct serio *serio)
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 
-	serio_raw->serio = NULL;
+	serio_raw->dead = true;
 	wake_up_interruptible(&serio_raw->wait);
 	kref_put(&serio_raw->kref, serio_raw_cleanup);
 
-- 
1.7.6.4


  parent reply	other threads:[~2011-10-06  5:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-06  5:08 [PATCH 1/9] Input: serio-raw - use kref instead of rolling out its own refcounting Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 2/9] Input: serio_raw - rename serio_raw_list to serio_raw_client Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 3/9] Input: serio_raw - perform proper locking when adding clients to list Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 4/9] Input: serio_raw - use bool for boolean data Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 5/9] Input: serio_raw - use dev_*() for messages Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 6/9] Input: serio_raw - fix coding style issues Dmitry Torokhov
2011-10-06  5:08 ` Dmitry Torokhov [this message]
2011-10-06  5:08 ` [PATCH 8/9] Input: serio_raw - kick clients when disconnecting port Dmitry Torokhov
2011-10-06  5:08 ` [PATCH 9/9] Input: serio_raw - fix memory leak when closing char device Dmitry Torokhov
2011-10-06  6:05 ` [PATCH 1/9] Input: serio-raw - use kref instead of rolling out its own refcounting Wanlong Gao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1317877696-7719-7-git-send-email-dmitry.torokhov@gmail.com \
    --to=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=ttuttle@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).