fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / irda / stir4200.c
index 648a713..20d306f 100644 (file)
@@ -15,8 +15,7 @@
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
+*      the Free Software Foundation; either version 2 of the License.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -50,6 +49,8 @@
 #include <linux/delay.h>
 #include <linux/usb.h>
 #include <linux/crc32.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
 #include <net/irda/irda.h>
 #include <net/irda/irlap.h>
 #include <net/irda/irda_device.h>
@@ -58,7 +59,7 @@
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
-MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200");
 MODULE_LICENSE("GPL");
 
@@ -148,8 +149,6 @@ enum StirFifoCtlMask {
        FIFOCTL_DIR = 0x10,
        FIFOCTL_CLR = 0x08,
        FIFOCTL_EMPTY = 0x04,
-       FIFOCTL_RXERR = 0x02,
-       FIFOCTL_TXERR = 0x01,
 };
 
 enum StirDiagMask {
@@ -173,9 +172,7 @@ struct stir_cb {
         struct qos_info   qos;
        unsigned          speed;        /* Current speed */
 
-       wait_queue_head_t thr_wait;     /* transmit thread wakeup */
-       struct completion thr_exited;
-       pid_t             thr_pid;
+        struct task_struct *thread;     /* transmit thread */
 
        struct sk_buff    *tx_pending;
        void              *io_buf;      /* transmit/receive buffer */
@@ -208,7 +205,7 @@ static int write_reg(struct stir_cb *stir, __u16 reg, __u8 value)
                               REQ_WRITE_SINGLE,
                               USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
                               value, reg, NULL, 0,
-                              msecs_to_jiffies(CTRL_TIMEOUT));
+                              CTRL_TIMEOUT);
 }
 
 /* Send control message to read multiple registers */
@@ -221,7 +218,7 @@ static inline int read_reg(struct stir_cb *stir, __u16 reg,
                               REQ_READ_REG,
                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                               0, reg, data, count,
-                              msecs_to_jiffies(CTRL_TIMEOUT));
+                              CTRL_TIMEOUT);
 }
 
 static inline int isfir(u32 speed)
@@ -577,7 +574,7 @@ static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        SKB_LINEAR_ASSERT(skb);
 
        skb = xchg(&stir->tx_pending, skb);
-       wake_up(&stir->thr_wait);
+        wake_up_process(stir->thread);
        
        /* this should never happen unless stop/wakeup problem */
        if (unlikely(skb)) {
@@ -616,19 +613,6 @@ static int fifo_txwait(struct stir_cb *stir, int space)
 
                pr_debug("fifo status 0x%lx count %lu\n", status, count);
 
-               /* error when receive/transmit fifo gets confused */
-               if (status & FIFOCTL_RXERR) {
-                       stir->stats.rx_fifo_errors++;
-                       stir->stats.rx_errors++;
-                       break;
-               }
-
-               if (status & FIFOCTL_TXERR) {
-                       stir->stats.tx_fifo_errors++;
-                       stir->stats.tx_errors++;
-                       break;
-               }
-
                /* is fifo receiving already, or empty */
                if (!(status & FIFOCTL_DIR)
                    || (status & FIFOCTL_EMPTY))
@@ -671,16 +655,16 @@ static void turnaround_delay(const struct stir_cb *stir, long us)
                return;
 
        do_gettimeofday(&now);
-       us -= (now.tv_sec - stir->rx_time.tv_sec) * USEC_PER_SEC;
+       if (now.tv_sec - stir->rx_time.tv_sec > 0)
+               us -= USEC_PER_SEC;
        us -= now.tv_usec - stir->rx_time.tv_usec;
        if (us < 10)
                return;
 
        ticks = us / (1000000 / HZ);
-       if (ticks > 0) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1 + ticks);
-       } else
+       if (ticks > 0)
+               schedule_timeout_interruptible(1 + ticks);
+       else
                udelay(us);
 }
 
@@ -740,7 +724,7 @@ static void stir_send(struct stir_cb *stir, struct sk_buff *skb)
 
        if (usb_bulk_msg(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1),
                         stir->io_buf, wraplen,
-                        NULL, msecs_to_jiffies(TRANSMIT_TIMEOUT)))
+                        NULL, TRANSMIT_TIMEOUT))
                stir->stats.tx_errors++;
 }
 
@@ -753,16 +737,10 @@ static int stir_transmit_thread(void *arg)
        struct net_device *dev = stir->netdev;
        struct sk_buff *skb;
 
-       daemonize("%s", dev->name);
-       allow_signal(SIGTERM);
-
-       while (netif_running(dev)
-              && netif_device_present(dev)
-              && !signal_pending(current))
-       {
+        while (!kthread_should_stop()) {
 #ifdef CONFIG_PM
                /* if suspending, then power off and wait */
-               if (unlikely(current->flags & PF_FREEZE)) {
+               if (unlikely(freezing(current))) {
                        if (stir->receiving)
                                receive_stop(stir);
                        else
@@ -770,7 +748,7 @@ static int stir_transmit_thread(void *arg)
 
                        write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
 
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
 
                        if (change_speed(stir, stir->speed))
                                break;
@@ -787,7 +765,7 @@ static int stir_transmit_thread(void *arg)
                                stir_send(stir, skb);
                        dev_kfree_skb(skb);
 
-                       if (stir->speed != new_speed) {
+                       if ((new_speed != -1) && (stir->speed != new_speed)) {
                                if (fifo_txwait(stir, -1) ||
                                    change_speed(stir, new_speed))
                                        break;
@@ -813,10 +791,11 @@ static int stir_transmit_thread(void *arg)
                }
 
                /* sleep if nothing to send */
-               wait_event_interruptible(stir->thr_wait, stir->tx_pending);
-       }
+                set_current_state(TASK_INTERRUPTIBLE);
+                schedule();
 
-       complete_and_exit (&stir->thr_exited, 0);
+       }
+        return 0;
 }
 
 
@@ -825,7 +804,7 @@ static int stir_transmit_thread(void *arg)
  * Wakes up every ms (usb round trip) with wrapped 
  * data.
  */
-static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs)
+static void stir_rcv_irq(struct urb *urb)
 {
        struct stir_cb *stir = urb->context;
        int err;
@@ -859,7 +838,7 @@ static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs)
                warn("%s: usb receive submit error: %d",
                        stir->netdev->name, err);
                stir->receiving = 0;
-               wake_up(&stir->thr_wait);
+               wake_up_process(stir->thread);
        }
 }
 
@@ -928,10 +907,10 @@ static int stir_net_open(struct net_device *netdev)
        }
 
        /** Start kernel thread for transmit.  */
-       stir->thr_pid = kernel_thread(stir_transmit_thread, stir,
-                                     CLONE_FS|CLONE_FILES);
-       if (stir->thr_pid < 0) {
-               err = stir->thr_pid;
+       stir->thread = kthread_run(stir_transmit_thread, stir,
+                                  "%s", stir->netdev->name);
+        if (IS_ERR(stir->thread)) {
+                err = PTR_ERR(stir->thread);
                err("stir4200: unable to start kernel thread");
                goto err_out6;
        }
@@ -968,8 +947,7 @@ static int stir_net_close(struct net_device *netdev)
        netif_stop_queue(netdev);
 
        /* Kill transmit thread */
-       kill_proc(stir->thr_pid, SIGTERM, 1);
-       wait_for_completion(&stir->thr_exited);
+       kthread_stop(stir->thread);
        kfree(stir->fifo_status);
 
        /* Mop up receive urb's */
@@ -1084,9 +1062,6 @@ static int stir_probe(struct usb_interface *intf,
        stir->qos.min_turn_time.bits   &= qos_mtt_bits;
        irda_qos_bits_to_value(&stir->qos);
 
-       init_completion (&stir->thr_exited);
-       init_waitqueue_head (&stir->thr_wait);
-
        /* Override the network functions we need to use */
        net->hard_start_xmit = stir_hard_xmit;
        net->open            = stir_net_open;
@@ -1127,8 +1102,8 @@ static void stir_disconnect(struct usb_interface *intf)
 }
 
 #ifdef CONFIG_PM
-/* Power management suspend, so power off the transmitter/receiver */
-static int stir_suspend(struct usb_interface *intf, u32 state)
+/* USB suspend, so power off the transmitter/receiver */
+static int stir_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct stir_cb *stir = usb_get_intfdata(intf);
 
@@ -1152,7 +1127,6 @@ static int stir_resume(struct usb_interface *intf)
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-       .owner          = THIS_MODULE,
        .name           = "stir4200",
        .probe          = stir_probe,
        .disconnect     = stir_disconnect,