From: Dominik Brodowski <linux@dominikbrodowski.net>

struct socket_data wasn't zeroed, so pcmcia_validate_mem() didn't get called.
If it is called, though, one possible code-path already holds skt_sem, so
lockups occur. Therefore, change calling conventions to pcmcia_validate_mem().

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/pcmcia/ds.c             |    4 ++++
 25-akpm/drivers/pcmcia/rsrc_nonstatic.c |    8 ++------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff -puN drivers/pcmcia/ds.c~pcmcia-dont-lock-up-in-rsrc_nonstatic-pcmcia_validate_mem drivers/pcmcia/ds.c
--- 25/drivers/pcmcia/ds.c~pcmcia-dont-lock-up-in-rsrc_nonstatic-pcmcia_validate_mem	2005-03-20 16:12:35.000000000 -0800
+++ 25-akpm/drivers/pcmcia/ds.c	2005-03-20 16:12:35.000000000 -0800
@@ -1386,7 +1386,9 @@ static int ds_ioctl(struct inode * inode
 			buf->config.Function, &buf->config);
 	break;
     case DS_GET_FIRST_TUPLE:
+	down(&s->parent->skt_sem);
 	pcmcia_validate_mem(s->parent);
+	up(&s->parent->skt_sem);
 	ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf->tuple);
 	break;
     case DS_GET_NEXT_TUPLE:
@@ -1412,7 +1414,9 @@ static int ds_ioctl(struct inode * inode
 	ret = pccard_get_status(s->parent, buf->status.Function, &buf->status);
 	break;
     case DS_VALIDATE_CIS:
+	down(&s->parent->skt_sem);
 	pcmcia_validate_mem(s->parent);
+	up(&s->parent->skt_sem);
 	ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo);
 	break;
     case DS_SUSPEND_CARD:
diff -puN drivers/pcmcia/rsrc_nonstatic.c~pcmcia-dont-lock-up-in-rsrc_nonstatic-pcmcia_validate_mem drivers/pcmcia/rsrc_nonstatic.c
--- 25/drivers/pcmcia/rsrc_nonstatic.c~pcmcia-dont-lock-up-in-rsrc_nonstatic-pcmcia_validate_mem	2005-03-20 16:12:35.000000000 -0800
+++ 25-akpm/drivers/pcmcia/rsrc_nonstatic.c	2005-03-20 16:12:35.000000000 -0800
@@ -474,8 +474,7 @@ static void validate_mem(struct pcmcia_s
 
 
 /*
- * Locking note: this is the only place where we take
- * both rsrc_sem and skt_sem.
+ * Locking note: Must be called with skt_sem held!
  */
 static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 {
@@ -492,12 +491,8 @@ static void pcmcia_nonstatic_validate_me
 		if (probe_mask & ~s_data->rsrc_mem_probe) {
 			s_data->rsrc_mem_probe |= probe_mask;
 
-			down(&s->skt_sem);
-
 			if (s->state & SOCKET_PRESENT)
 				validate_mem(s, probe_mask);
-
-			up(&s->skt_sem);
 		}
 
 		up(&rsrc_sem);
@@ -781,6 +776,7 @@ static int nonstatic_init(struct pcmcia_
 	data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
+	memset(data, 0, sizeof(struct socket_data));
 
 	data->mem_db.next = &data->mem_db;
 	data->io_db.next = &data->io_db;
_