Linux PARISC architecture development
 help / color / mirror / Atom feed
* [parisc-linux] SMP kernel hangs on C360, resolved
@ 2005-08-03 19:49 Richard Hirst
  0 siblings, 0 replies; only message in thread
From: Richard Hirst @ 2005-08-03 19:49 UTC (permalink / raw)
  To: parisc-linux

[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]

Turns out this is down to bugs in drivers/input/serio/gscps2.c.
Looking at gscps2_probe(), there are two locks involved; one in
struct gscps2port and one in struct serio.  The probe function
initialises the one in struct gscps2port and then calls gscps2_reset()
which enables the device such that it can start generating interrupts,
then adds the port to the list of ports the int handler looks at,
then calls serio_register_port() which initialises the lock in
struct serio.  gscps2_interrupt() calls serio_interrupt(), so
if an interrupt is raised before serio_register_port() is called,
the code will hang trying to claim the serio lock which has not yet
been initialised.  Another issue is that gscps2_reset() resets the
device _and_ enables the port.  I think enabling the port should
only happen once something calls open().

The attached patch addresses these issues.  Before applying the
patch I could provoke the hang easily after adding an mdelay() to
the middle of the probe function and then banging on the keyboard
and mouse during boot.

Richard



[-- Attachment #2: dd --]
[-- Type: text/plain, Size: 1258 bytes --]

Index: drivers/input/serio/gscps2.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/input/serio/gscps2.c,v
retrieving revision 1.16
diff -u -r1.16 gscps2.c
--- drivers/input/serio/gscps2.c	18 Mar 2005 13:16:54 -0000	1.16
+++ drivers/input/serio/gscps2.c	3 Aug 2005 19:22:35 -0000
@@ -211,9 +211,6 @@
 	writeb(0xff, addr+GSC_RESET);
 	gscps2_flush(ps2port);
 	spin_unlock_irqrestore(&ps2port->lock, flags);
-
-	/* enable it */
-	gscps2_enable(ps2port, ENABLE);
 }
 
 static LIST_HEAD(ps2port_list);
@@ -307,6 +304,9 @@
 
 	gscps2_reset(ps2port);
 
+	/* enable it */
+	gscps2_enable(ps2port, ENABLE);
+
 	gscps2_interrupt(0, NULL, NULL);
 
 	return 0;
@@ -370,8 +370,6 @@
 	serio->port_data	= ps2port;
 	serio->dev.parent	= &dev->dev;
 
-	list_add_tail(&ps2port->node, &ps2port_list);
-
 	ret = -EBUSY;
 	if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
 		goto fail_miserably;
@@ -396,13 +394,14 @@
 
 	serio_register_port(ps2port->port);
 
+	list_add_tail(&ps2port->node, &ps2port_list);
+
 	return 0;
 
 fail:
 	free_irq(dev->irq, ps2port);
 
 fail_miserably:
-	list_del(&ps2port->node);
 	iounmap(ps2port->addr);
 	release_mem_region(dev->hpa, GSC_STATUS + 4);
 

[-- Attachment #3: Type: text/plain, Size: 169 bytes --]

_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-08-03 19:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-03 19:49 [parisc-linux] SMP kernel hangs on C360, resolved Richard Hirst

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