From: Dominik Brodowski 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 Signed-off-by: Andrew Morton --- 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; _