Commit caf3413d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

[PATCH] fix module refcounting of pcmcia socket drivers

parent 6fe56a9f
...@@ -244,7 +244,14 @@ static const lookup_t service_table[] = { ...@@ -244,7 +244,14 @@ static const lookup_t service_table[] = {
static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info) static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info)
{ {
return s->ss_entry->register_callback(s->sock, handler, info); int error;
if (handler && !try_module_get(s->ss_entry->owner))
return -ENODEV;
error = s->ss_entry->register_callback(s->sock, handler, info);
if (!handler)
module_put(s->ss_entry->owner);
return error;
} }
static int get_socket_status(socket_info_t *s, int *val) static int get_socket_status(socket_info_t *s, int *val)
......
...@@ -394,11 +394,6 @@ static int hs_register_callback(unsigned int sock, ...@@ -394,11 +394,6 @@ static int hs_register_callback(unsigned int sock,
DPRINTK("hs_register_callback(%d)\n", sock); DPRINTK("hs_register_callback(%d)\n", sock);
sp->handler = handler; sp->handler = handler;
sp->handler_info = info; sp->handler_info = info;
if (handler == 0) {
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
}
return 0; return 0;
} }
...@@ -891,18 +886,19 @@ static void hs_interrupt(int irq, void *dev, struct pt_regs *regs) ...@@ -891,18 +886,19 @@ static void hs_interrupt(int irq, void *dev, struct pt_regs *regs)
/*============================================================*/ /*============================================================*/
static struct pccard_operations hs_operations = { static struct pccard_operations hs_operations = {
hs_init, .owner = THIS_MODULE,
hs_suspend, .init = hs_init,
hs_register_callback, .suspend = hs_suspend,
hs_inquire_socket, .register_callback = hs_register_callback,
hs_get_status, .inquire_socket = hs_inquire_socket,
hs_get_socket, .get_status = hs_get_status,
hs_set_socket, .get_socket = hs_get_socket,
hs_get_io_map, .set_socket = hs_set_socket,
hs_set_io_map, .get_io_map = hs_get_io_map,
hs_get_mem_map, .set_io_map = hs_set_io_map,
hs_set_mem_map, .get_mem_map = hs_get_mem_map,
hs_proc_setup .set_mem_map = hs_set_mem_map,
.proc_setup = hs_proc_setup,
}; };
static int hs_init_socket(hs_socket_t *sp, int irq, unsigned long mem_base, static int hs_init_socket(hs_socket_t *sp, int irq, unsigned long mem_base,
......
...@@ -55,6 +55,7 @@ static struct pci_driver i82092aa_pci_drv = { ...@@ -55,6 +55,7 @@ static struct pci_driver i82092aa_pci_drv = {
/* the pccard structure and its functions */ /* the pccard structure and its functions */
static struct pccard_operations i82092aa_operations = { static struct pccard_operations i82092aa_operations = {
.owner = THIS_MODULE,
.init = i82092aa_init, .init = i82092aa_init,
.suspend = i82092aa_suspend, .suspend = i82092aa_suspend,
.register_callback = i82092aa_register_callback, .register_callback = i82092aa_register_callback,
...@@ -465,11 +466,6 @@ static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, ...@@ -465,11 +466,6 @@ static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *,
enter("i82092aa_register_callback"); enter("i82092aa_register_callback");
sockets[sock].handler = handler; sockets[sock].handler = handler;
sockets[sock].info = info; sockets[sock].info = info;
if (handler == NULL) {
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
}
leave("i82092aa_register_callback"); leave("i82092aa_register_callback");
return 0; return 0;
} /* i82092aa_register_callback */ } /* i82092aa_register_callback */
......
...@@ -1018,11 +1018,6 @@ static int pcic_register_callback(unsigned int sock, void (*handler)(void *, uns ...@@ -1018,11 +1018,6 @@ static int pcic_register_callback(unsigned int sock, void (*handler)(void *, uns
{ {
socket[sock].handler = handler; socket[sock].handler = handler;
socket[sock].info = info; socket[sock].info = info;
if (handler == NULL) {
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
}
return 0; return 0;
} /* pcic_register_callback */ } /* pcic_register_callback */
...@@ -1568,18 +1563,19 @@ static int pcic_suspend(unsigned int sock) ...@@ -1568,18 +1563,19 @@ static int pcic_suspend(unsigned int sock)
} }
static struct pccard_operations pcic_operations = { static struct pccard_operations pcic_operations = {
pcic_init, .owner = THIS_MODULE,
pcic_suspend, .init = pcic_init,
pcic_register_callback, .suspend = pcic_suspend,
pcic_inquire_socket, .register_callback = pcic_register_callback,
pcic_get_status, .inquire_socket = pcic_inquire_socket,
pcic_get_socket, .get_status = pcic_get_status,
pcic_set_socket, .get_socket = pcic_get_socket,
pcic_get_io_map, .set_socket = pcic_set_socket,
pcic_set_io_map, .get_io_map = pcic_get_io_map,
pcic_get_mem_map, .set_io_map = pcic_set_io_map,
pcic_set_mem_map, .get_mem_map = pcic_get_mem_map,
pcic_proc_setup .set_mem_map = pcic_set_mem_map,
.proc_setup = pcic_proc_setup,
}; };
/*====================================================================*/ /*====================================================================*/
......
...@@ -66,10 +66,6 @@ static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsi ...@@ -66,10 +66,6 @@ static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsi
socket->handler = handler; socket->handler = handler;
socket->info = info; socket->info = info;
if (handler)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -154,18 +150,19 @@ static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base) ...@@ -154,18 +150,19 @@ static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
} }
static struct pccard_operations pci_socket_operations = { static struct pccard_operations pci_socket_operations = {
pci_init_socket, .owner = THIS_MODULE,
pci_suspend_socket, .init = pci_init_socket,
pci_register_callback, .suspend = pci_suspend_socket,
pci_inquire_socket, .register_callback = pci_register_callback,
pci_get_status, .inquire_socket = pci_inquire_socket,
pci_get_socket, .get_status = pci_get_status,
pci_set_socket, .get_socket = pci_get_socket,
pci_get_io_map, .set_socket = pci_set_socket,
pci_set_io_map, .get_io_map = pci_get_io_map,
pci_get_mem_map, .set_io_map = pci_set_io_map,
pci_set_mem_map, .get_mem_map = pci_get_mem_map,
pci_proc_setup .set_mem_map = pci_set_mem_map,
.proc_setup = pci_proc_setup,
}; };
static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops) static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
......
...@@ -380,9 +380,7 @@ sa1100_pcmcia_register_callback(unsigned int sock, ...@@ -380,9 +380,7 @@ sa1100_pcmcia_register_callback(unsigned int sock,
if (handler == NULL) { if (handler == NULL) {
skt->handler = NULL; skt->handler = NULL;
MOD_DEC_USE_COUNT;
} else { } else {
MOD_INC_USE_COUNT;
skt->handler_info = info; skt->handler_info = info;
skt->handler = handler; skt->handler = handler;
} }
...@@ -854,6 +852,7 @@ sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) ...@@ -854,6 +852,7 @@ sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
#endif /* defined(CONFIG_PROC_FS) */ #endif /* defined(CONFIG_PROC_FS) */
static struct pccard_operations sa1100_pcmcia_operations = { static struct pccard_operations sa1100_pcmcia_operations = {
.owner = THIS_MODULE,
.init = sa1100_pcmcia_sock_init, .init = sa1100_pcmcia_sock_init,
.suspend = sa1100_pcmcia_suspend, .suspend = sa1100_pcmcia_suspend,
.register_callback = sa1100_pcmcia_register_callback, .register_callback = sa1100_pcmcia_register_callback,
......
...@@ -638,11 +638,6 @@ static int tcic_register_callback(unsigned int lsock, void (*handler)(void *, un ...@@ -638,11 +638,6 @@ static int tcic_register_callback(unsigned int lsock, void (*handler)(void *, un
{ {
socket_table[lsock].handler = handler; socket_table[lsock].handler = handler;
socket_table[lsock].info = info; socket_table[lsock].info = info;
if (handler == NULL) {
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
}
return 0; return 0;
} /* tcic_register_callback */ } /* tcic_register_callback */
...@@ -1003,6 +998,7 @@ static int tcic_suspend(unsigned int sock) ...@@ -1003,6 +998,7 @@ static int tcic_suspend(unsigned int sock)
} }
static struct pccard_operations tcic_operations = { static struct pccard_operations tcic_operations = {
.owner = THIS_MODULE,
.init = tcic_init, .init = tcic_init,
.suspend = tcic_suspend, .suspend = tcic_suspend,
.register_callback = tcic_register_callback, .register_callback = tcic_register_callback,
......
...@@ -126,6 +126,7 @@ typedef struct cb_bridge_map { ...@@ -126,6 +126,7 @@ typedef struct cb_bridge_map {
* Socket operations. * Socket operations.
*/ */
struct pccard_operations { struct pccard_operations {
struct module *owner;
int (*init)(unsigned int sock); int (*init)(unsigned int sock);
int (*suspend)(unsigned int sock); int (*suspend)(unsigned int sock);
int (*register_callback)(unsigned int sock, void (*handler)(void *, unsigned int), void * info); int (*register_callback)(unsigned int sock, void (*handler)(void *, unsigned int), void * info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment