On Fri, Apr 14, 2006 at 08:20:15PM +0200, Christoph Hellwig wrote:
> sir_kthread.c pretty much duplicates the workqueue functionality.
> Switch it to use a workqueue instead.  It could probably use
> schedule_work/schedule_delayed_work instead of having it's own
> waitqueue, but I'd rather leave that to the maintainer.  The file
> should probably get a name that still makes sense or merged into
> sir-dev.c now, but again that's up to the maintainer.
> 
> Note: I don't have the hardware so this is just compile-tested.
> 
> 
> Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]>

        Samuel Ortiz is in charge and has some shiny new Actisys
dongles ;-)

        Jean

> Index: linux-2.6/drivers/net/irda/sir-dev.h
> ===================================================================
> --- linux-2.6.orig/drivers/net/irda/sir-dev.h 2006-01-31 12:23:36.000000000 
> +0100
> +++ linux-2.6/drivers/net/irda/sir-dev.h      2006-04-14 15:08:14.000000000 
> +0200
> @@ -15,23 +15,15 @@
>  #define IRDA_SIR_H
>  
>  #include <linux/netdevice.h>
> +#include <linux/workqueue.h>
>  
>  #include <net/irda/irda.h>
>  #include <net/irda/irda_device.h>            // iobuff_t
>  
> -/* FIXME: unify irda_request with sir_fsm! */
> -
> -struct irda_request {
> -     struct list_head lh_request;
> -     unsigned long pending;
> -     void (*func)(void *);
> -     void *data;
> -     struct timer_list timer;
> -};
>  
>  struct sir_fsm {
>       struct semaphore        sem;
> -     struct irda_request     rq;
> +     struct work_struct      work;
>       unsigned                state, substate;
>       int                     param;
>       int                     result;
> Index: linux-2.6/drivers/net/irda/sir_dev.c
> ===================================================================
> --- linux-2.6.orig/drivers/net/irda/sir_dev.c 2006-04-14 15:02:46.000000000 
> +0200
> +++ linux-2.6/drivers/net/irda/sir_dev.c      2006-04-14 15:03:15.000000000 
> +0200
> @@ -619,10 +619,6 @@
>       spin_lock_init(&dev->tx_lock);
>       init_MUTEX(&dev->fsm.sem);
>  
> -     INIT_LIST_HEAD(&dev->fsm.rq.lh_request);
> -     dev->fsm.rq.pending = 0;
> -     init_timer(&dev->fsm.rq.timer);
> -
>       dev->drv = drv;
>       dev->netdev = ndev;
>  
> Index: linux-2.6/drivers/net/irda/sir_kthread.c
> ===================================================================
> --- linux-2.6.orig/drivers/net/irda/sir_kthread.c     2006-04-14 
> 14:54:08.000000000 +0200
> +++ linux-2.6/drivers/net/irda/sir_kthread.c  2006-04-14 15:10:56.000000000 
> +0200
> @@ -14,159 +14,14 @@
>  
>  #include <linux/module.h>
>  #include <linux/kernel.h>
> -#include <linux/version.h>
>  #include <linux/init.h>
> -#include <linux/smp_lock.h>
> -#include <linux/completion.h>
>  #include <linux/delay.h>
> -
>  #include <net/irda/irda.h>
>  
>  #include "sir-dev.h"
>  
> -/**************************************************************************
> - *
> - * kIrDAd kernel thread and config state machine
> - *
> - */
> -
> -struct irda_request_queue {
> -     struct list_head request_list;
> -     spinlock_t lock;
> -     task_t *thread;
> -     struct completion exit;
> -     wait_queue_head_t kick, done;
> -     atomic_t num_pending;
> -};
> -
> -static struct irda_request_queue irda_rq_queue;
> -
> -static int irda_queue_request(struct irda_request *rq)
> -{
> -     int ret = 0;
> -     unsigned long flags;
> -
> -     if (!test_and_set_bit(0, &rq->pending)) {
> -             spin_lock_irqsave(&irda_rq_queue.lock, flags);
> -             list_add_tail(&rq->lh_request, &irda_rq_queue.request_list);
> -             wake_up(&irda_rq_queue.kick);
> -             atomic_inc(&irda_rq_queue.num_pending);
> -             spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
> -             ret = 1;
> -     }
> -     return ret;
> -}
> -
> -static void irda_request_timer(unsigned long data)
> -{
> -     struct irda_request *rq = (struct irda_request *)data;
> -     unsigned long flags;
> -     
> -     spin_lock_irqsave(&irda_rq_queue.lock, flags);
> -     list_add_tail(&rq->lh_request, &irda_rq_queue.request_list);
> -     wake_up(&irda_rq_queue.kick);
> -     spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
> -}
> -
> -static int irda_queue_delayed_request(struct irda_request *rq, unsigned long 
> delay)
> -{
> -     int ret = 0;
> -     struct timer_list *timer = &rq->timer;
>  
> -     if (!test_and_set_bit(0, &rq->pending)) {
> -             timer->expires = jiffies + delay;
> -             timer->function = irda_request_timer;
> -             timer->data = (unsigned long)rq;
> -             atomic_inc(&irda_rq_queue.num_pending);
> -             add_timer(timer);
> -             ret = 1;
> -     }
> -     return ret;
> -}
> -
> -static void run_irda_queue(void)
> -{
> -     unsigned long flags;
> -     struct list_head *entry, *tmp;
> -     struct irda_request *rq;
> -
> -     spin_lock_irqsave(&irda_rq_queue.lock, flags);
> -     list_for_each_safe(entry, tmp, &irda_rq_queue.request_list) {
> -             rq = list_entry(entry, struct irda_request, lh_request);
> -             list_del_init(entry);
> -             spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
> -
> -             clear_bit(0, &rq->pending);
> -             rq->func(rq->data);
> -
> -             if (atomic_dec_and_test(&irda_rq_queue.num_pending))
> -                     wake_up(&irda_rq_queue.done);
> -
> -             spin_lock_irqsave(&irda_rq_queue.lock, flags);
> -     }
> -     spin_unlock_irqrestore(&irda_rq_queue.lock, flags);
> -}            
> -
> -static int irda_thread(void *startup)
> -{
> -     DECLARE_WAITQUEUE(wait, current);
> -
> -     daemonize("kIrDAd");
> -
> -     irda_rq_queue.thread = current;
> -
> -     complete((struct completion *)startup);
> -
> -     while (irda_rq_queue.thread != NULL) {
> -
> -             /* We use TASK_INTERRUPTIBLE, rather than
> -              * TASK_UNINTERRUPTIBLE.  Andrew Morton made this
> -              * change ; he told me that it is safe, because "signal
> -              * blocking is now handled in daemonize()", he added
> -              * that the problem is that "uninterruptible sleep
> -              * contributes to load average", making user worry.
> -              * Jean II */
> -             set_task_state(current, TASK_INTERRUPTIBLE);
> -             add_wait_queue(&irda_rq_queue.kick, &wait);
> -             if (list_empty(&irda_rq_queue.request_list))
> -                     schedule();
> -             else
> -                     __set_task_state(current, TASK_RUNNING);
> -             remove_wait_queue(&irda_rq_queue.kick, &wait);
> -
> -             /* make swsusp happy with our thread */
> -             try_to_freeze();
> -
> -             run_irda_queue();
> -     }
> -
> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,35)
> -     reparent_to_init();
> -#endif
> -     complete_and_exit(&irda_rq_queue.exit, 0);
> -     /* never reached */
> -     return 0;
> -}
> -
> -
> -static void flush_irda_queue(void)
> -{
> -     if (atomic_read(&irda_rq_queue.num_pending)) {
> -
> -             DECLARE_WAITQUEUE(wait, current);
> -
> -             if (!list_empty(&irda_rq_queue.request_list))
> -                     run_irda_queue();
> -
> -             set_task_state(current, TASK_UNINTERRUPTIBLE);
> -             add_wait_queue(&irda_rq_queue.done, &wait);
> -             if (atomic_read(&irda_rq_queue.num_pending))
> -                     schedule();
> -             else
> -                     __set_task_state(current, TASK_RUNNING);
> -             remove_wait_queue(&irda_rq_queue.done, &wait);
> -     }
> -}
> +static struct workqueue_struct *irda_wq;
>  
>  /* substate handler of the config-fsm to handle the cases where we want
>   * to wait for transmit completion before changing the port configuration
> @@ -413,7 +268,7 @@
>               fsm->state = next_state;
>       } while(!delay);
>  
> -     irda_queue_delayed_request(&fsm->rq, msecs_to_jiffies(delay));
> +     queue_delayed_work(irda_wq, &fsm->work, msecs_to_jiffies(delay));
>  }
>  
>  /* schedule some device configuration task for execution by kIrDAd
> @@ -424,7 +279,6 @@
>  int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned 
> param)
>  {
>       struct sir_fsm *fsm = &dev->fsm;
> -     int xmit_was_down;
>  
>       IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, 
> initial_state, param);
>  
> @@ -443,7 +297,6 @@
>               return -ESTALE;         /* or better EPIPE? */
>       }
>  
> -     xmit_was_down = netif_queue_stopped(dev->netdev);
>       netif_stop_queue(dev->netdev);
>       atomic_set(&dev->enable_rx, 0);
>  
> @@ -451,58 +304,27 @@
>       fsm->param = param;
>       fsm->result = 0;
>  
> -     INIT_LIST_HEAD(&fsm->rq.lh_request);
> -     fsm->rq.pending = 0;
> -     fsm->rq.func = irda_config_fsm;
> -     fsm->rq.data = dev;
> -
> -     if (!irda_queue_request(&fsm->rq)) {    /* returns 0 on error! */
> -             atomic_set(&dev->enable_rx, 1);
> -             if (!xmit_was_down)
> -                     netif_wake_queue(dev->netdev);          
> -             up(&fsm->sem);
> -             return -EAGAIN;
> -     }
> +     INIT_WORK(&fsm->work, irda_config_fsm, dev);
> +     queue_work(irda_wq, &fsm->work);
>       return 0;
>  }
>  
> -static int __init irda_thread_create(void)
> +static int __init irda_thread_init(void)
>  {
> -     struct completion startup;
> -     int pid;
> -
> -     spin_lock_init(&irda_rq_queue.lock);
> -     irda_rq_queue.thread = NULL;
> -     INIT_LIST_HEAD(&irda_rq_queue.request_list);
> -     init_waitqueue_head(&irda_rq_queue.kick);
> -     init_waitqueue_head(&irda_rq_queue.done);
> -     atomic_set(&irda_rq_queue.num_pending, 0);
> -
> -     init_completion(&startup);
> -     pid = kernel_thread(irda_thread, &startup, CLONE_FS|CLONE_FILES);
> -     if (pid <= 0)
> -             return -EAGAIN;
> -     else
> -             wait_for_completion(&startup);
> -
> +     irda_wq = create_singlethread_workqueue("irda_wq");
> +     if (!irda_wq)
> +             return -ENOMEM;
>       return 0;
>  }
>  
> -static void __exit irda_thread_join(void)
> +static void __exit irda_thread_exit(void)
>  {
> -     if (irda_rq_queue.thread) {
> -             flush_irda_queue();
> -             init_completion(&irda_rq_queue.exit);
> -             irda_rq_queue.thread = NULL;
> -             wake_up(&irda_rq_queue.kick);           
> -             wait_for_completion(&irda_rq_queue.exit);
> -     }
> +     destroy_workqueue(irda_wq);
>  }
>  
> -module_init(irda_thread_create);
> -module_exit(irda_thread_join);
> +module_init(irda_thread_init);
> +module_exit(irda_thread_exit);
>  
>  MODULE_AUTHOR("Martin Diehl <[EMAIL PROTECTED]>");
>  MODULE_DESCRIPTION("IrDA SIR core");
>  MODULE_LICENSE("GPL");
> -
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to