public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Input patches for 2.6.12
@ 2005-04-04  6:10 Dmitry Torokhov
  2005-04-04  6:11 ` [PATCH 1/4] serio resume fix Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2005-04-04  6:10 UTC (permalink / raw)
  To: Vojtech Pavlik, LKML, InputML, Andrew Morton

Hi Vojtech,

I have some patches that I would like to get in before 2.6.12 is out:

01-serio-resume-fix.patch
  - do not attempt to disconnect port in resume handler if reconect
    failed - let kseriod handle it. This fixes problem with swsusp
    resuming devices before writing the image. If reconnect fails
    at this point serio core will try to disconnect port and unregister
    associated input device invoking hotplug which will block since
    the system is half-frozen.

02-alps-reconnect-fix.patch
  - apparently ALPS needs a reset before it starts responding with
    proper IDs to the E6/E7 queries.

03-serport-oops-fix.patch
  - serport should not call serio_interrupt or serio_write_wakeup on
    unregistered port (happens if you move mouse aroung while shutting
    down the system), also dynamic serio allocation needed to be reworked
    to awoid memory leaks in case serport was never used.

04-serio-id-attribute-group.patch
  - move serio port's 'id' attributes into separate subdirectory using
    attribute group:
	..devices/serioX/id_type  -> ..devices/serioX/id/type
	..devices/serioX/id_proto -> ..devices/serioX/id/proto
    ID attributes were never part of a released kernel so if we were to
    do the change now would be the time. 

I have confirmation reports for patches 1-3. Please let me know what you
think.

Thanks!
 
-- 
Dmitry

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] serio resume fix
  2005-04-04  6:10 [PATCH 0/4] Input patches for 2.6.12 Dmitry Torokhov
@ 2005-04-04  6:11 ` Dmitry Torokhov
  2005-04-04  6:11   ` [PATCH 2/4] ALPS " Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2005-04-04  6:11 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML, InputML, Andrew Morton

===================================================================

Input: serio - do not attempt to immediately disconnect port if
       resume failed, let kseriod take care of it. Otherwise we
       may attempt to unregister associated input devices which
       will generate hotplug events which are not handled well
       during swsusp.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serio.c |    1 -
 1 files changed, 1 deletion(-)

Index: dtor/drivers/input/serio/serio.c
===================================================================
--- dtor.orig/drivers/input/serio/serio.c
+++ dtor/drivers/input/serio/serio.c
@@ -779,7 +779,6 @@ static int serio_resume(struct device *d
 	struct serio *serio = to_serio_port(dev);
 
 	if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
-		serio_disconnect_port(serio);
 		/*
 		 * Driver re-probing can take a while, so better let kseriod
 		 * deal with it.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/4] ALPS resume fix
  2005-04-04  6:11 ` [PATCH 1/4] serio resume fix Dmitry Torokhov
@ 2005-04-04  6:11   ` Dmitry Torokhov
  2005-04-04  6:13     ` [PATCH 3/4] serport oops fix Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2005-04-04  6:11 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML, InputML, Andrew Morton

===================================================================

Input: ALPS needs to be reset for detection to work reliably when
       reconnecting.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 alps.c |    2 ++
 1 files changed, 2 insertions(+)

Index: dtor/drivers/input/mouse/alps.c
===================================================================
--- dtor.orig/drivers/input/mouse/alps.c
+++ dtor/drivers/input/mouse/alps.c
@@ -341,6 +341,8 @@ static int alps_reconnect(struct psmouse
 	unsigned char param[4];
 	int version;
 
+	psmouse_reset(psmouse);
+
 	if (!(priv->i = alps_get_model(psmouse, &version)))
 		return -1;
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/4] serport oops fix
  2005-04-04  6:11   ` [PATCH 2/4] ALPS " Dmitry Torokhov
@ 2005-04-04  6:13     ` Dmitry Torokhov
  2005-04-04  6:13       ` [PATCH 4/4] serio 'id' attributes Dmitry Torokhov
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2005-04-04  6:13 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML, InputML, Andrew Morton

===================================================================

Input: serport - avoid calling serio_interrupt or serio_write_wakeup
       on unregistered port. Also fix memory leak which could happen
       if serport was left unused by moving serio allocation down to
       serport_ldisc_read.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serport.c |   98 +++++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 68 insertions(+), 30 deletions(-)

Index: dtor/drivers/input/serio/serport.c
===================================================================
--- dtor.orig/drivers/input/serio/serport.c
+++ dtor/drivers/input/serio/serport.c
@@ -27,11 +27,15 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_MOUSE);
 
 #define SERPORT_BUSY	1
+#define SERPORT_ACTIVE	2
+#define SERPORT_DEAD	3
 
 struct serport {
 	struct tty_struct *tty;
 	wait_queue_head_t wait;
 	struct serio *serio;
+	struct serio_device_id id;
+	spinlock_t lock;
 	unsigned long flags;
 };
 
@@ -45,11 +49,29 @@ static int serport_serio_write(struct se
 	return -(serport->tty->driver->write(serport->tty, &data, 1) != 1);
 }
 
+static int serport_serio_open(struct serio *serio)
+{
+	struct serport *serport = serio->port_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serport->lock, flags);
+	set_bit(SERPORT_ACTIVE, &serport->flags);
+	spin_unlock_irqrestore(&serport->lock, flags);
+
+	return 0;
+}
+
+
 static void serport_serio_close(struct serio *serio)
 {
 	struct serport *serport = serio->port_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serport->lock, flags);
+	clear_bit(SERPORT_ACTIVE, &serport->flags);
+	set_bit(SERPORT_DEAD, &serport->flags);
+	spin_unlock_irqrestore(&serport->lock, flags);
 
-	serport->serio->id.type = 0;
 	wake_up_interruptible(&serport->wait);
 }
 
@@ -61,36 +83,21 @@ static void serport_serio_close(struct s
 static int serport_ldisc_open(struct tty_struct *tty)
 {
 	struct serport *serport;
-	struct serio *serio;
-	char name[64];
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
-	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-	if (unlikely(!serport || !serio)) {
-		kfree(serport);
-		kfree(serio);
+	serport = kcalloc(1, sizeof(struct serport), GFP_KERNEL);
+	if (!serport)
 		return -ENOMEM;
-	}
 
-	memset(serport, 0, sizeof(struct serport));
-	serport->serio = serio;
-	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 	serport->tty = tty;
-	tty->disc_data = serport;
-
-	memset(serio, 0, sizeof(struct serio));
-	strlcpy(serio->name, "Serial port", sizeof(serio->name));
-	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
-	serio->id.type = SERIO_RS232;
-	serio->write = serport_serio_write;
-	serio->close = serport_serio_close;
-	serio->port_data = serport;
-
+	spin_lock_init(&serport->lock);
 	init_waitqueue_head(&serport->wait);
 
+	tty->disc_data = serport;
+	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+
 	return 0;
 }
 
@@ -100,7 +107,8 @@ static int serport_ldisc_open(struct tty
 
 static void serport_ldisc_close(struct tty_struct *tty)
 {
-	struct serport *serport = (struct serport*) tty->disc_data;
+	struct serport *serport = (struct serport *) tty->disc_data;
+
 	kfree(serport);
 }
 
@@ -116,9 +124,19 @@ static void serport_ldisc_close(struct t
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
+	unsigned long flags;
 	int i;
+
+	spin_lock_irqsave(&serport->lock, flags);
+
+	if (!test_bit(SERPORT_ACTIVE, &serport->flags))
+		goto out;
+
 	for (i = 0; i < count; i++)
 		serio_interrupt(serport->serio, cp[i], 0, NULL);
+
+out:
+	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
@@ -141,16 +159,33 @@ static int serport_ldisc_room(struct tty
 static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
+	struct serio *serio;
 	char name[64];
 
 	if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
 		return -EBUSY;
 
+	serport->serio = serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
+	if (!serio)
+		return -ENOMEM;
+
+	strlcpy(serio->name, "Serial port", sizeof(serio->name));
+	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
+	serio->id = serport->id;
+	serio->id.type = SERIO_RS232;
+	serio->write = serport_serio_write;
+	serio->open = serport_serio_open;
+	serio->close = serport_serio_close;
+	serio->port_data = serport;
+
 	serio_register_port(serport->serio);
 	printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
-	wait_event_interruptible(serport->wait, !serport->serio->id.type);
+
+	wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags));
 	serio_unregister_port(serport->serio);
+	serport->serio = NULL;
 
+	clear_bit(SERPORT_DEAD, &serport->flags);
 	clear_bit(SERPORT_BUSY, &serport->flags);
 
 	return 0;
@@ -163,16 +198,15 @@ static ssize_t serport_ldisc_read(struct
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
-	struct serio *serio = serport->serio;
 	unsigned long type;
 
 	if (cmd == SPIOCSTYPE) {
 		if (get_user(type, (unsigned long __user *) arg))
 			return -EFAULT;
 
-		serio->id.proto	= type & 0x000000ff;
-		serio->id.id	= (type & 0x0000ff00) >> 8;
-		serio->id.extra	= (type & 0x00ff0000) >> 16;
+		serport->id.proto = type & 0x000000ff;
+		serport->id.id	  = (type & 0x0000ff00) >> 8;
+		serport->id.extra = (type & 0x00ff0000) >> 16;
 
 		return 0;
 	}
@@ -182,9 +216,13 @@ static int serport_ldisc_ioctl(struct tt
 
 static void serport_ldisc_write_wakeup(struct tty_struct * tty)
 {
-	struct serport *sp = (struct serport *) tty->disc_data;
+	struct serport *serport = (struct serport *) tty->disc_data;
+	unsigned long flags;
 
-	serio_drv_write_wakeup(sp->serio);
+	spin_lock_irqsave(&serport->lock, flags);
+	if (test_bit(SERPORT_ACTIVE, &serport->flags))
+		serio_drv_write_wakeup(serport->serio);
+	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/4] serio 'id' attributes
  2005-04-04  6:13     ` [PATCH 3/4] serport oops fix Dmitry Torokhov
@ 2005-04-04  6:13       ` Dmitry Torokhov
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry Torokhov @ 2005-04-04  6:13 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: LKML, InputML, Andrew Morton

===================================================================

Input: move serio port's id attributes into separate subdirectory:
       ..devices/serioX/id_type  -> ..devices/serioX/id/type
       ..devices/serioX/id_proto -> ..devices/serioX/id/proto

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serio.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

Index: dtor/drivers/input/serio/serio.c
===================================================================
--- dtor.orig/drivers/input/serio/serio.c
+++ dtor/drivers/input/serio/serio.c
@@ -388,6 +388,24 @@ static ssize_t serio_show_id_extra(struc
 	return sprintf(buf, "%02x\n", serio->id.extra);
 }
 
+static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL);
+static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL);
+static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL);
+static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL);
+
+static struct attribute *serio_device_id_attrs[] = {
+	&dev_attr_type.attr,
+	&dev_attr_proto.attr,
+	&dev_attr_id.attr,
+	&dev_attr_extra.attr,
+	NULL
+};
+
+static struct attribute_group serio_id_attr_group = {
+	.name	= "id",
+	.attrs	= serio_device_id_attrs,
+};
+
 static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
 {
 	struct serio *serio = to_serio_port(dev);
@@ -444,10 +462,6 @@ static ssize_t serio_set_bind_mode(struc
 
 static struct device_attribute serio_device_attrs[] = {
 	__ATTR(description, S_IRUGO, serio_show_description, NULL),
-	__ATTR(id_type, S_IRUGO, serio_show_id_type, NULL),
-	__ATTR(id_proto, S_IRUGO, serio_show_id_proto, NULL),
-	__ATTR(id_id, S_IRUGO, serio_show_id_id, NULL),
-	__ATTR(id_extra, S_IRUGO, serio_show_id_extra, NULL),
 	__ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
 	__ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
 	__ATTR_NULL
@@ -498,6 +512,7 @@ static void serio_add_port(struct serio 
 	if (serio->start)
 		serio->start(serio);
 	device_add(&serio->dev);
+	sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
 	serio->registered = 1;
 }
 
@@ -526,6 +541,7 @@ static void serio_destroy_port(struct se
 	}
 
 	if (serio->registered) {
+		sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
 		device_del(&serio->dev);
 		list_del_init(&serio->node);
 		serio->registered = 0;

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-04  6:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-04  6:10 [PATCH 0/4] Input patches for 2.6.12 Dmitry Torokhov
2005-04-04  6:11 ` [PATCH 1/4] serio resume fix Dmitry Torokhov
2005-04-04  6:11   ` [PATCH 2/4] ALPS " Dmitry Torokhov
2005-04-04  6:13     ` [PATCH 3/4] serport oops fix Dmitry Torokhov
2005-04-04  6:13       ` [PATCH 4/4] serio 'id' attributes Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox