From: Dominik Brodowski BUG if the socket's list of clients is not empty on shutdown and/or removal. Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton --- 25-akpm/drivers/pcmcia/cs.c | 19 ++----------------- 25-akpm/drivers/pcmcia/ds.c | 13 +++++++------ 2 files changed, 9 insertions(+), 23 deletions(-) diff -puN drivers/pcmcia/cs.c~pcmcia-bug-if-clients-are-kept-too-long drivers/pcmcia/cs.c --- 25/drivers/pcmcia/cs.c~pcmcia-bug-if-clients-are-kept-too-long Mon Dec 13 14:39:04 2004 +++ 25-akpm/drivers/pcmcia/cs.c Mon Dec 13 14:39:04 2004 @@ -198,13 +198,8 @@ EXPORT_SYMBOL(pcmcia_put_socket); static void pcmcia_release_socket(struct class_device *class_dev) { struct pcmcia_socket *socket = class_get_devdata(class_dev); - client_t *client; - while (socket->clients) { - client = socket->clients; - socket->clients = socket->clients->next; - kfree(client); - } + BUG_ON(socket->clients); complete(&socket->socket_released); } @@ -357,8 +352,6 @@ static void free_regions(memory_handle_t static void shutdown_socket(struct pcmcia_socket *s) { - client_t **c; - cs_dbg(s, 1, "shutdown_socket\n"); /* Blank out the socket state */ @@ -376,15 +369,7 @@ static void shutdown_socket(struct pcmci kfree(s->config); s->config = NULL; } - for (c = &s->clients; *c; ) { - if ((*c)->state & CLIENT_UNBOUND) { - client_t *d = *c; - *c = (*c)->next; - kfree(d); - } else { - c = &((*c)->next); - } - } + BUG_ON(s->clients); free_regions(&s->a_region); free_regions(&s->c_region); diff -puN drivers/pcmcia/ds.c~pcmcia-bug-if-clients-are-kept-too-long drivers/pcmcia/ds.c --- 25/drivers/pcmcia/ds.c~pcmcia-bug-if-clients-are-kept-too-long Mon Dec 13 14:39:04 2004 +++ 25-akpm/drivers/pcmcia/ds.c Mon Dec 13 14:39:04 2004 @@ -907,15 +907,13 @@ int pcmcia_deregister_client(client_hand s = SOCKET(handle); ds_dbg(1, "deregister_client(%p)\n", handle); - if (handle->state & - (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) - return CS_IN_USE; + if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) + goto warn_out; for (i = 0; i < MAX_WIN; i++) if (handle->state & CLIENT_WIN_REQ(i)) - return CS_IN_USE; + goto warn_out; - if ((handle->state & CLIENT_STALE) || - (handle->Attributes & INFO_MASTER_CLIENT)) { + if (handle->state & CLIENT_STALE) { spin_lock_irqsave(&s->lock, flags); client = &s->clients; while ((*client) && ((*client) != handle)) @@ -934,6 +932,9 @@ int pcmcia_deregister_client(client_hand } return CS_SUCCESS; + warn_out: + printk(KERN_WARNING "ds: deregister_client was called too early.\n"); + return CS_IN_USE; } /* deregister_client */ EXPORT_SYMBOL(pcmcia_deregister_client); _