Grab a reference of struct pcmcia_socket for every struct pcmcia_bus_socket. drivers/pcmcia/ds.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c --- linux-original/drivers/pcmcia/ds.c 2004-11-13 14:08:55.074725024 +0100 +++ linux/drivers/pcmcia/ds.c 2004-11-13 14:10:56.565255656 +0100 @@ -384,6 +384,7 @@ static void pcmcia_release_bus_socket(struct kref *refcount) { struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount); + pcmcia_put_socket(s->parent); kfree(s); } @@ -1242,7 +1243,7 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) { - struct pcmcia_socket *socket = class_dev->class_data; + struct pcmcia_socket *socket = class_get_devdata(class_dev); struct pcmcia_bus_socket *s; int ret; @@ -1250,6 +1251,15 @@ if(!s) return -ENOMEM; memset(s, 0, sizeof(struct pcmcia_bus_socket)); + + /* get reference to parent socket */ + s->parent = pcmcia_get_socket(socket); + if (!s->parent) { + printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); + kfree (s); + return -ENODEV; + } + kref_init(&s->refcount); /* @@ -1262,9 +1272,6 @@ init_waitqueue_head(&s->request); INIT_LIST_HEAD(&s->devices_list); - /* initialize data */ - s->parent = socket; - /* Set up hotline to Card Services */ s->callback.owner = THIS_MODULE; s->callback.event = &ds_event; @@ -1284,7 +1291,7 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev) { - struct pcmcia_socket *socket = class_dev->class_data; + struct pcmcia_socket *socket = class_get_devdata(class_dev); if (!socket || !socket->pcmcia) return;