Commit e9692fa4 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Russell King

[PCMCIA] Move get_socket_info_by_nr

This adds a list of all pcmcia sockets which will replace the current
table-based approach. Also, ds.c now relies on cs.c to get the proper
"struct pcmcia_bus_socket *" for the corresponding socket number.
parent b04860b1
...@@ -128,6 +128,11 @@ socket_state_t dead_socket = { ...@@ -128,6 +128,11 @@ socket_state_t dead_socket = {
socket_t sockets = 0; socket_t sockets = 0;
socket_info_t *socket_table[MAX_SOCK]; socket_info_t *socket_table[MAX_SOCK];
/* List of all sockets, protected by a rwsem */
static LIST_HEAD(pcmcia_socket_list);
static DECLARE_RWSEM(pcmcia_socket_list_rwsem);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_pccard = NULL; struct proc_dir_entry *proc_pccard = NULL;
#endif #endif
...@@ -349,6 +354,9 @@ int pcmcia_register_socket(struct class_device *class_dev) ...@@ -349,6 +354,9 @@ int pcmcia_register_socket(struct class_device *class_dev)
if (socket_table[j] == NULL) break; if (socket_table[j] == NULL) break;
socket_table[j] = s; socket_table[j] = s;
if (j == sockets) sockets++; if (j == sockets) sockets++;
down_write(&pcmcia_socket_list_rwsem);
list_add(&s->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
init_socket(s); init_socket(s);
s->ss_entry->inquire_socket(s->sock, &s->cap); s->ss_entry->inquire_socket(s->sock, &s->cap);
...@@ -432,7 +440,13 @@ void pcmcia_unregister_socket(struct class_device *class_dev) ...@@ -432,7 +440,13 @@ void pcmcia_unregister_socket(struct class_device *class_dev)
s->clients = s->clients->next; s->clients = s->clients->next;
kfree(client); kfree(client);
} }
down_write(&pcmcia_socket_list_rwsem);
list_del(&s->socket_list);
up_write(&pcmcia_socket_list_rwsem);
s->ss_entry = NULL; s->ss_entry = NULL;
socket_table[socket] = NULL; socket_table[socket] = NULL;
for (j = socket; j < sockets-1; j++) for (j = socket; j < sockets-1; j++)
socket_table[j] = socket_table[j+1]; socket_table[j] = socket_table[j+1];
...@@ -444,6 +458,24 @@ void pcmcia_unregister_socket(struct class_device *class_dev) ...@@ -444,6 +458,24 @@ void pcmcia_unregister_socket(struct class_device *class_dev)
} /* pcmcia_unregister_socket */ } /* pcmcia_unregister_socket */
struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
{
struct pcmcia_socket *s;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list)
if (s->sock == nr) {
up_read(&pcmcia_socket_list_rwsem);
return s;
}
up_read(&pcmcia_socket_list_rwsem);
return NULL;
}
EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
/*====================================================================== /*======================================================================
Shutdown_Socket() and setup_socket() are scheduled using add_timer Shutdown_Socket() and setup_socket() are scheduled using add_timer
......
...@@ -109,6 +109,7 @@ struct pcmcia_bus_socket { ...@@ -109,6 +109,7 @@ struct pcmcia_bus_socket {
struct device *socket_dev; struct device *socket_dev;
struct list_head socket_list; struct list_head socket_list;
unsigned int socket_no; /* deprecated */ unsigned int socket_no; /* deprecated */
struct pcmcia_socket *parent;
}; };
#define SOCKET_PRESENT 0x01 #define SOCKET_PRESENT 0x01
...@@ -832,13 +833,12 @@ static struct file_operations ds_fops = { ...@@ -832,13 +833,12 @@ static struct file_operations ds_fops = {
.poll = ds_poll, .poll = ds_poll,
}; };
static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int socket_nr) static int __devinit pcmcia_bus_add_socket(struct pcmcia_socket *socket, struct device *dev, unsigned int socket_nr)
{ {
client_reg_t client_reg; client_reg_t client_reg;
bind_req_t bind; bind_req_t bind;
struct pcmcia_bus_socket *s, *tmp_s; struct pcmcia_bus_socket *s;
int ret; int ret;
int i;
s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL); s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
if(!s) if(!s)
...@@ -855,24 +855,12 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock ...@@ -855,24 +855,12 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
init_waitqueue_head(&s->queue); init_waitqueue_head(&s->queue);
init_waitqueue_head(&s->request); init_waitqueue_head(&s->request);
/* find the lowest, unused socket no. Please note that this is a
* temporary workaround until "struct pcmcia_socket" is introduced
* into cs.c which will include this number, and which will be
* accessible to ds.c directly */
i = 0;
next_try:
list_for_each_entry(tmp_s, &bus_socket_list, socket_list) {
if (tmp_s->socket_no == i) {
i++;
goto next_try;
}
}
s->socket_no = i;
/* initialize data */ /* initialize data */
s->socket_dev = dev; s->socket_dev = dev;
INIT_WORK(&s->removal, handle_removal, s); INIT_WORK(&s->removal, handle_removal, s);
s->socket_no = socket->sock;
s->parent = socket;
/* Set up hotline to Card Services */ /* Set up hotline to Card Services */
client_reg.dev_info = bind.dev_info = &dev_info; client_reg.dev_info = bind.dev_info = &dev_info;
...@@ -901,6 +889,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock ...@@ -901,6 +889,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
return -EINVAL; return -EINVAL;
} }
socket->pcmcia = s;
list_add(&s->socket_list, &bus_socket_list); list_add(&s->socket_list, &bus_socket_list);
return 0; return 0;
...@@ -918,7 +907,7 @@ static int pcmcia_bus_add_socket_dev(struct class_device *class_dev) ...@@ -918,7 +907,7 @@ static int pcmcia_bus_add_socket_dev(struct class_device *class_dev)
down_write(&bus_socket_list_rwsem); down_write(&bus_socket_list_rwsem);
for (i = 0; i < cls_d->nsock; i++) for (i = 0; i < cls_d->nsock; i++)
ret += pcmcia_bus_add_socket(class_dev->dev, i); ret += pcmcia_bus_add_socket(&cls_d->s_info[i], class_dev->dev, i);
up_write(&bus_socket_list_rwsem); up_write(&bus_socket_list_rwsem);
return ret; return ret;
...@@ -939,6 +928,7 @@ static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev) ...@@ -939,6 +928,7 @@ static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) { list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) {
struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list); struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list);
if (bus_sock->socket_dev == class_dev->dev) { if (bus_sock->socket_dev == class_dev->dev) {
bus_sock->parent.pcmcia = NULL;
pcmcia_deregister_client(bus_sock->handle); pcmcia_deregister_client(bus_sock->handle);
list_del(&bus_sock->socket_list); list_del(&bus_sock->socket_list);
kfree(bus_sock); kfree(bus_sock);
...@@ -1008,18 +998,13 @@ module_exit(exit_pcmcia_bus); ...@@ -1008,18 +998,13 @@ module_exit(exit_pcmcia_bus);
/* helpers for backwards-compatible functions */ /* helpers for backwards-compatible functions */
static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr) static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
{ {
struct pcmcia_bus_socket * s; struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
down_read(&bus_socket_list_rwsem); if (s && s->pcmcia)
list_for_each_entry(s, &bus_socket_list, socket_list) return s->pcmcia;
if (s->socket_no == nr) { else
up_read(&bus_socket_list_rwsem); return NULL;
return s;
}
up_read(&bus_socket_list_rwsem);
return NULL;
} }
/* backwards-compatible accessing of driver --- by name! */ /* backwards-compatible accessing of driver --- by name! */
......
...@@ -201,7 +201,6 @@ struct region_t; ...@@ -201,7 +201,6 @@ struct region_t;
struct pcmcia_socket { struct pcmcia_socket {
spinlock_t lock; spinlock_t lock;
struct pccard_operations * ss_entry; struct pccard_operations * ss_entry;
u_int sock;
socket_state_t socket; socket_state_t socket;
socket_cap_t cap; socket_cap_t cap;
u_int state; u_int state;
...@@ -224,7 +223,11 @@ struct pcmcia_socket { ...@@ -224,7 +223,11 @@ struct pcmcia_socket {
u_int fake_cis_len; u_int fake_cis_len;
char *fake_cis; char *fake_cis;
/* deprecated */ struct list_head socket_list;
/* deprecated */
unsigned int sock; /* socket number */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc; struct proc_dir_entry *proc;
#endif #endif
...@@ -239,7 +242,7 @@ struct pcmcia_socket { ...@@ -239,7 +242,7 @@ struct pcmcia_socket {
unsigned int thread_events; unsigned int thread_events;
/* pcmcia (16-bit) */ /* pcmcia (16-bit) */
struct pcmcia_bus_socket *pcmcia;
/* cardbus (32-bit) */ /* cardbus (32-bit) */
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
...@@ -248,5 +251,6 @@ struct pcmcia_socket { ...@@ -248,5 +251,6 @@ struct pcmcia_socket {
#endif #endif
}; };
__deprecated struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
#endif /* _LINUX_SS_H */ #endif /* _LINUX_SS_H */
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