linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / pcmcia / cs.c
index f9cd831..613f2f1 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/major.h>
 #include <linux/errno.h>
@@ -28,7 +29,6 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/device.h>
-#include <linux/kthread.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 
@@ -111,9 +111,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
        list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
                if (socket->dev.dev != dev)
                        continue;
-               mutex_lock(&socket->skt_mutex);
+               down(&socket->skt_sem);
                socket_suspend(socket);
-               mutex_unlock(&socket->skt_mutex);
+               up(&socket->skt_sem);
        }
        up_read(&pcmcia_socket_list_rwsem);
 
@@ -129,9 +129,9 @@ int pcmcia_socket_dev_resume(struct device *dev)
        list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
                if (socket->dev.dev != dev)
                        continue;
-               mutex_lock(&socket->skt_mutex);
+               down(&socket->skt_sem);
                socket_resume(socket);
-               mutex_unlock(&socket->skt_mutex);
+               up(&socket->skt_sem);
        }
        up_read(&pcmcia_socket_list_rwsem);
 
@@ -177,7 +177,6 @@ static int pccardd(void *__skt);
  */
 int pcmcia_register_socket(struct pcmcia_socket *socket)
 {
-       struct task_struct *tsk;
        int ret;
 
        if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops)
@@ -238,21 +237,18 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
        init_completion(&socket->socket_released);
        init_completion(&socket->thread_done);
        init_waitqueue_head(&socket->thread_wait);
-       mutex_init(&socket->skt_mutex);
+       init_MUTEX(&socket->skt_sem);
        spin_lock_init(&socket->thread_lock);
 
-       tsk = kthread_run(pccardd, socket, "pccardd");
-       if (IS_ERR(tsk)) {
-               ret = PTR_ERR(tsk);
+       ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
+       if (ret < 0)
                goto err;
-       }
 
        wait_for_completion(&socket->thread_done);
-       if (!socket->thread) {
+       if(!socket->thread) {
                printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
                return -EIO;
        }
-
        pcmcia_parse_events(socket, SS_DETECT);
 
        return 0;
@@ -277,8 +273,10 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
        cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
 
        if (socket->thread) {
+               init_completion(&socket->thread_done);
+               socket->thread = NULL;
                wake_up(&socket->thread_wait);
-               kthread_stop(socket->thread);
+               wait_for_completion(&socket->thread_done);
        }
        release_cis_mem(socket);
 
@@ -408,6 +406,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
        cb_free(s);
 #endif
        s->functions = 0;
+       kfree(s->config);
+       s->config = NULL;
 
        s->ops->get_status(s, &status);
        if (status & SS_POWERON) {
@@ -633,6 +633,8 @@ static int pccardd(void *__skt)
        DECLARE_WAITQUEUE(wait, current);
        int ret;
 
+       daemonize("pccardd");
+
        skt->thread = current;
        skt->socket = dead_socket;
        skt->ops->init(skt);
@@ -644,8 +646,7 @@ static int pccardd(void *__skt)
                printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
                        skt);
                skt->thread = NULL;
-               complete(&skt->thread_done);
-               return 0;
+               complete_and_exit(&skt->thread_done, 0);
        }
 
        add_wait_queue(&skt->thread_wait, &wait);
@@ -663,7 +664,7 @@ static int pccardd(void *__skt)
                spin_unlock_irqrestore(&skt->thread_lock, flags);
 
                if (events) {
-                       mutex_lock(&skt->skt_mutex);
+                       down(&skt->skt_sem);
                        if (events & SS_DETECT)
                                socket_detect_change(skt);
                        if (events & SS_BATDEAD)
@@ -672,11 +673,11 @@ static int pccardd(void *__skt)
                                send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
                        if (events & SS_READY)
                                send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
-                       mutex_unlock(&skt->skt_mutex);
+                       up(&skt->skt_sem);
                        continue;
                }
 
-               if (kthread_should_stop())
+               if (!skt->thread)
                        break;
 
                schedule();
@@ -690,7 +691,7 @@ static int pccardd(void *__skt)
        /* remove from the device core */
        class_device_unregister(&skt->dev);
 
-       return 0;
+       complete_and_exit(&skt->thread_done, 0);
 }
 
 /*
@@ -699,12 +700,11 @@ static int pccardd(void *__skt)
  */
 void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
 {
-       unsigned long flags;
        cs_dbg(s, 4, "parse_events: events %08x\n", events);
        if (s->thread) {
-               spin_lock_irqsave(&s->thread_lock, flags);
+               spin_lock(&s->thread_lock);
                s->thread_events |= events;
-               spin_unlock_irqrestore(&s->thread_lock, flags);
+               spin_unlock(&s->thread_lock);
 
                wake_up(&s->thread_wait);
        }
@@ -717,8 +717,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
 {
         int ret = 0;
 
-       /* s->skt_mutex also protects s->callback */
-       mutex_lock(&s->skt_mutex);
+       /* s->skt_sem also protects s->callback */
+       down(&s->skt_sem);
 
        if (c) {
                /* registration */
@@ -734,7 +734,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
        } else
                s->callback = NULL;
  err:
-       mutex_unlock(&s->skt_mutex);
+       up(&s->skt_sem);
 
        return ret;
 }
@@ -752,7 +752,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
 
        cs_dbg(skt, 1, "resetting socket\n");
 
-       mutex_lock(&skt->skt_mutex);
+       down(&skt->skt_sem);
        do {
                if (!(skt->state & SOCKET_PRESENT)) {
                        ret = CS_NO_CARD;
@@ -781,7 +781,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
 
                ret = CS_SUCCESS;
        } while (0);
-       mutex_unlock(&skt->skt_mutex);
+       up(&skt->skt_sem);
 
        return ret;
 } /* reset_card */
@@ -797,7 +797,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
 
        cs_dbg(skt, 1, "suspending socket\n");
 
-       mutex_lock(&skt->skt_mutex);
+       down(&skt->skt_sem);
        do {
                if (!(skt->state & SOCKET_PRESENT)) {
                        ret = CS_NO_CARD;
@@ -814,7 +814,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
                }
                ret = socket_suspend(skt);
        } while (0);
-       mutex_unlock(&skt->skt_mutex);
+       up(&skt->skt_sem);
 
        return ret;
 } /* suspend_card */
@@ -827,7 +827,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
     
        cs_dbg(skt, 1, "waking up socket\n");
 
-       mutex_lock(&skt->skt_mutex);
+       down(&skt->skt_sem);
        do {
                if (!(skt->state & SOCKET_PRESENT)) {
                        ret = CS_NO_CARD;
@@ -841,7 +841,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
                if (!ret && skt->callback)
                        skt->callback->resume(skt);
        } while (0);
-       mutex_unlock(&skt->skt_mutex);
+       up(&skt->skt_sem);
 
        return ret;
 } /* resume_card */
@@ -855,7 +855,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
     
        cs_dbg(skt, 1, "user eject request\n");
 
-       mutex_lock(&skt->skt_mutex);
+       down(&skt->skt_sem);
        do {
                if (!(skt->state & SOCKET_PRESENT)) {
                        ret = -ENODEV;
@@ -871,7 +871,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
                socket_remove(skt);
                ret = 0;
        } while (0);
-       mutex_unlock(&skt->skt_mutex);
+       up(&skt->skt_sem);
 
        return ret;
 } /* eject_card */
@@ -884,7 +884,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
 
        cs_dbg(skt, 1, "user insert request\n");
 
-       mutex_lock(&skt->skt_mutex);
+       down(&skt->skt_sem);
        do {
                if (skt->state & SOCKET_PRESENT) {
                        ret = -EBUSY;
@@ -896,7 +896,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
                }
                ret = 0;
        } while (0);
-       mutex_unlock(&skt->skt_mutex);
+       up(&skt->skt_sem);
 
        return ret;
 } /* insert_card */