[PATCH] pcmcia: split socket initialization
Dominik Brodowski
linux at brodo.de
Sat May 17 23:13:27 BST 2003
Split up the socket initialization in cs.c into two pieces:
pcmcia_register_socket / pcmcia_unregister_socket
will focus on registering sockets with the device core in future, set
all necessary fields etc.
pcmcia_add_socket / pcmcia_remove_socket
will use an interface to the device class "pcmcia_socket_class" in
future, and mainly take care of what initialization cs.c needs to work
properly.
The actual "work" will be done in the next patch -- this one
only shuffles code around.
drivers/pcmcia/cs.c | 160 +++++++++++++++++++++++++++++-----------------------
include/pcmcia/ss.h | 1
2 files changed, 93 insertions(+), 68 deletions(-)
diff -ruN linux-original/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- linux-original/drivers/pcmcia/cs.c 2003-05-17 20:57:56.000000000 +0200
+++ linux/drivers/pcmcia/cs.c 2003-05-17 20:56:37.000000000 +0200
@@ -322,6 +322,90 @@
}
+static int pcmcia_add_socket(struct pcmcia_socket *socket)
+{
+ socket_info_t *s;
+ int ret;
+
+ s = (socket_info_t *) socket->s_info;
+ /* socket initialization */
+ s->ss_entry = socket->ops;
+ s->sock = socket->socket_no;
+
+ /* base address = 0, map = 0 */
+ s->cis_mem.flags = 0;
+ s->cis_mem.speed = cis_speed;
+ s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
+ INIT_LIST_HEAD(&s->cis_cache);
+ spin_lock_init(&s->lock);
+
+ init_socket(s);
+ s->ss_entry->inquire_socket(s->sock, &s->cap);
+
+ init_completion(&s->thread_done);
+ init_waitqueue_head(&s->thread_wait);
+ init_MUTEX(&s->skt_sem);
+ spin_lock_init(&s->thread_lock);
+ ret = kernel_thread(pccardd, s, CLONE_KERNEL);
+ if (ret < 0) {
+ /* pcmcia_unregister_socket(class_dev); */
+ return ret;
+ }
+
+ wait_for_completion(&s->thread_done);
+ BUG_ON(!s->thread);
+
+#ifdef CONFIG_PROC_FS
+ if (proc_pccard) {
+ char name[3];
+ sprintf(name, "%02d", s->sock);
+ s->proc = proc_mkdir(name, proc_pccard);
+ if (s->proc)
+ s->ss_entry->proc_setup(s->sock, s->proc);
+#ifdef PCMCIA_DEBUG
+ if (s->proc)
+ create_proc_read_entry("clients", 0, s->proc,
+ proc_read_clients, s);
+#endif
+ }
+#endif
+ return 0;
+}
+
+
+static void pcmcia_remove_socket(struct pcmcia_socket *socket)
+{
+ client_t *client;
+ socket_info_t *s;
+
+ s = (socket_info_t *) socket->s_info;
+
+#ifdef CONFIG_PROC_FS
+ if (proc_pccard) {
+ char name[3];
+ sprintf(name, "%02d", s->sock);
+#ifdef PCMCIA_DEBUG
+ remove_proc_entry("clients", s->proc);
+#endif
+ remove_proc_entry(name, proc_pccard);
+ }
+#endif
+ if (s->thread) {
+ init_completion(&s->thread_done);
+ s->thread = NULL;
+ wake_up(&s->thread_wait);
+ wait_for_completion(&s->thread_done);
+ }
+ release_cis_mem(s);
+ while (s->clients) {
+ client = s->clients;
+ s->clients = s->clients->next;
+ kfree(client);
+ }
+ s->ss_entry = NULL;
+}
+
+
/**
* pcmcia_register_socket - add a new pcmcia socket device
*/
@@ -347,59 +431,20 @@
/* socket initialization */
for (i = 0; i < cls_d->nsock; i++) {
- socket_info_t *s = &s_info[i];
-
- s->ss_entry = cls_d->ops;
- s->sock = i + cls_d->sock_offset;
-
- /* base address = 0, map = 0 */
- s->cis_mem.flags = 0;
- s->cis_mem.speed = cis_speed;
- s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
- INIT_LIST_HEAD(&s->cis_cache);
- spin_lock_init(&s->lock);
-
socket = kmalloc(sizeof(struct pcmcia_socket), GFP_KERNEL);
if (!socket)
return -ENOMEM;
memset(socket, 0, sizeof(struct pcmcia_socket));
- socket->s_info = (void *) s;
- socket->socket_no = s->sock;
+ socket->s_info = (void *) &s_info[i];
+ socket->socket_no = i + cls_d->sock_offset;
+ socket->ops = cls_d->ops;
+
down(&pcmcia_socket_list_lock);
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up(&pcmcia_socket_list_lock);
- init_socket(s);
- s->ss_entry->inquire_socket(s->sock, &s->cap);
-
- init_completion(&s->thread_done);
- init_waitqueue_head(&s->thread_wait);
- init_MUTEX(&s->skt_sem);
- spin_lock_init(&s->thread_lock);
- ret = kernel_thread(pccardd, s, CLONE_KERNEL);
- if (ret < 0) {
- pcmcia_unregister_socket(class_dev);
- break;
- }
-
- wait_for_completion(&s->thread_done);
- BUG_ON(!s->thread);
-
-#ifdef CONFIG_PROC_FS
- if (proc_pccard) {
- char name[3];
- sprintf(name, "%02d", s->sock);
- s->proc = proc_mkdir(name, proc_pccard);
- if (s->proc)
- s->ss_entry->proc_setup(i, s->proc);
-#ifdef PCMCIA_DEBUG
- if (s->proc)
- create_proc_read_entry("clients", 0, s->proc,
- proc_read_clients, s);
-#endif
- }
-#endif
+ pcmcia_add_socket(socket);
}
return ret;
} /* pcmcia_register_socket */
@@ -413,7 +458,6 @@
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
struct pcmcia_socket *socket;
unsigned int i;
- client_t *client;
socket_info_t *s;
if (!cls_d)
@@ -433,29 +477,9 @@
found:
up(&pcmcia_socket_list_lock);
-#ifdef CONFIG_PROC_FS
- if (proc_pccard) {
- char name[3];
- sprintf(name, "%02d", s->sock);
-#ifdef PCMCIA_DEBUG
- remove_proc_entry("clients", s->proc);
-#endif
- remove_proc_entry(name, proc_pccard);
- }
-#endif
- if (s->thread) {
- init_completion(&s->thread_done);
- s->thread = NULL;
- wake_up(&s->thread_wait);
- wait_for_completion(&s->thread_done);
- }
- release_cis_mem(s);
- while (s->clients) {
- client = s->clients;
- s->clients = s->clients->next;
- kfree(client);
- }
- s->ss_entry = NULL;
+
+ pcmcia_remove_socket(socket);
+
down(&pcmcia_socket_list_lock);
list_del(&socket->socket_list);
up(&pcmcia_socket_list_lock);
diff -ruN linux-original/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- linux-original/include/pcmcia/ss.h 2003-05-17 20:57:56.000000000 +0200
+++ linux/include/pcmcia/ss.h 2003-05-17 20:52:59.000000000 +0200
@@ -144,6 +144,7 @@
struct pcmcia_socket {
struct list_head socket_list;
+ struct pccard_operations *ops;
/* deprecated */
unsigned int socket_no;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20030517/4e7d2be3/attachment.bin
More information about the linux-pcmcia
mailing list