Commit c6b71ca4 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390 update (9/27): bottom half removal.

Replace IMMEDIATE_BH bottom half by tasklets in 3215, ctc and iucv driver.
parent 73ba61b9
...@@ -89,7 +89,7 @@ typedef struct _raw3215_info { ...@@ -89,7 +89,7 @@ typedef struct _raw3215_info {
int written; /* number of bytes in write requests */ int written; /* number of bytes in write requests */
devstat_t devstat; /* device status structure for do_IO */ devstat_t devstat; /* device status structure for do_IO */
struct tty_struct *tty; /* pointer to tty structure if present */ struct tty_struct *tty; /* pointer to tty structure if present */
struct tq_struct tqueue; /* task queue to bottom half */ struct tasklet_struct tasklet;
raw3215_req *queued_read; /* pointer to queued read requests */ raw3215_req *queued_read; /* pointer to queued read requests */
raw3215_req *queued_write; /* pointer to queued write requests */ raw3215_req *queued_write; /* pointer to queued write requests */
wait_queue_head_t empty_wait; /* wait queue for flushing */ wait_queue_head_t empty_wait; /* wait queue for flushing */
...@@ -341,7 +341,7 @@ extern inline void raw3215_try_io(raw3215_info *raw) ...@@ -341,7 +341,7 @@ extern inline void raw3215_try_io(raw3215_info *raw)
* The bottom half handler routine for 3215 devices. It tries to start * The bottom half handler routine for 3215 devices. It tries to start
* the next IO and wakes up processes waiting on the tty. * the next IO and wakes up processes waiting on the tty.
*/ */
static void raw3215_softint(void *data) static void raw3215_tasklet(void *data)
{ {
raw3215_info *raw; raw3215_info *raw;
struct tty_struct *tty; struct tty_struct *tty;
...@@ -377,12 +377,7 @@ static inline void raw3215_sched_bh(raw3215_info *raw) ...@@ -377,12 +377,7 @@ static inline void raw3215_sched_bh(raw3215_info *raw)
if (raw->flags & RAW3215_BH_PENDING) if (raw->flags & RAW3215_BH_PENDING)
return; /* already pending */ return; /* already pending */
raw->flags |= RAW3215_BH_PENDING; raw->flags |= RAW3215_BH_PENDING;
INIT_LIST_HEAD(&raw->tqueue.list); tasklet_hi_schedule(&raw->tasklet);
raw->tqueue.sync = 0;
raw->tqueue.routine = raw3215_softint;
raw->tqueue.data = raw;
queue_task(&raw->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
} }
/* /*
...@@ -867,8 +862,9 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp) ...@@ -867,8 +862,9 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
kfree(raw); kfree(raw);
return -ENOMEM; return -ENOMEM;
} }
raw->tqueue.routine = raw3215_softint; tasklet_init(&raw->tasklet,
raw->tqueue.data = raw; (void (*)(unsigned long)) raw3215_tasklet,
(unsigned long) raw);
init_waitqueue_head(&raw->empty_wait); init_waitqueue_head(&raw->empty_wait);
raw3215[line] = raw; raw3215[line] = raw;
} }
...@@ -1095,10 +1091,11 @@ void __init con3215_init(void) ...@@ -1095,10 +1091,11 @@ void __init con3215_init(void)
raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
/* Find the first console */ /* Find the first console */
raw->irq = raw3215_find_dev(0); raw->irq = irq;
raw->flags |= RAW3215_FIXED; raw->flags |= RAW3215_FIXED;
raw->tqueue.routine = raw3215_softint; tasklet_init(&raw->tasklet,
raw->tqueue.data = raw; (void (*)(unsigned long)) raw3215_tasklet,
(unsigned long) raw);
init_waitqueue_head(&raw->empty_wait); init_waitqueue_head(&raw->empty_wait);
/* Request the console irq */ /* Request the console irq */
......
...@@ -229,12 +229,12 @@ fs3270_io(tub_t *tubp, ccw1_t *ccwp) ...@@ -229,12 +229,12 @@ fs3270_io(tub_t *tubp, ccw1_t *ccwp)
* fs3270_bh(tubp) -- Perform back-half processing * fs3270_bh(tubp) -- Perform back-half processing
*/ */
static void static void
fs3270_bh(void *data) fs3270_tasklet(unsigned long data)
{ {
long flags; long flags;
tub_t *tubp; tub_t *tubp;
tubp = data; tubp = (tub_t *) data;
TUBLOCK(tubp->irq, flags); TUBLOCK(tubp->irq, flags);
tubp->flags &= ~TUB_BHPENDING; tubp->flags &= ~TUB_BHPENDING;
...@@ -265,10 +265,9 @@ fs3270_sched_bh(tub_t *tubp) ...@@ -265,10 +265,9 @@ fs3270_sched_bh(tub_t *tubp)
if (tubp->flags & TUB_BHPENDING) if (tubp->flags & TUB_BHPENDING)
return; return;
tubp->flags |= TUB_BHPENDING; tubp->flags |= TUB_BHPENDING;
tubp->tqueue.routine = fs3270_bh; tasklet_init(&tubp->tasklet, fs3270_tasklet,
tubp->tqueue.data = tubp; (unsigned long) tubp);
queue_task(&tubp->tqueue, &tq_immediate); tasklet_schedule(&tubp->tasklet);
mark_bh(IMMEDIATE_BH);
} }
/* /*
......
...@@ -234,7 +234,7 @@ typedef struct tub_s { ...@@ -234,7 +234,7 @@ typedef struct tub_s {
enum tubstat stat; enum tubstat stat;
enum tubcmd cmd; enum tubcmd cmd;
int flags; /* See below for values */ int flags; /* See below for values */
struct tq_struct tqueue; struct tasklet_struct tasklet;
/* Stuff for fs-driver support */ /* Stuff for fs-driver support */
pid_t fs_pid; /* Pid if TBM_FS */ pid_t fs_pid; /* Pid if TBM_FS */
......
...@@ -35,7 +35,7 @@ static int tty3270_write_proc(struct file *, const char *, ...@@ -35,7 +35,7 @@ static int tty3270_write_proc(struct file *, const char *,
unsigned long, void *); unsigned long, void *);
/* tty3270 utility functions */ /* tty3270 utility functions */
static void tty3270_bh(void *); static void tty3270_tasklet(unsigned long);
void tty3270_sched_bh(tub_t *); void tty3270_sched_bh(tub_t *);
static int tty3270_wait(tub_t *, long *); static int tty3270_wait(tub_t *, long *);
void tty3270_int(tub_t *, devstat_t *); void tty3270_int(tub_t *, devstat_t *);
...@@ -598,17 +598,18 @@ tty3270_hangup(struct tty_struct *tty) ...@@ -598,17 +598,18 @@ tty3270_hangup(struct tty_struct *tty)
/* /*
* tty3270_bh(tubp) -- Perform back-half processing * tty3270_tasklet(tubp) -- Perform back-half processing
*/ */
static void static void
tty3270_bh(void *data) tty3270_tasklet(unsigned long data)
{ {
tub_t *tubp; tub_t *tubp;
ioinfo_t *ioinfop; ioinfo_t *ioinfop;
long flags; long flags;
struct tty_struct *tty; struct tty_struct *tty;
ioinfop = ioinfo[(tubp = data)->irq]; tubp = (tub_t *) data;
ioinfop = ioinfo[tubp->irq];
while (TUBTRYLOCK(tubp->irq, flags) == 0) { while (TUBTRYLOCK(tubp->irq, flags) == 0) {
if (ioinfop->ui.flags.unready == 1) if (ioinfop->ui.flags.unready == 1)
return; return;
...@@ -663,10 +664,9 @@ tty3270_sched_bh(tub_t *tubp) ...@@ -663,10 +664,9 @@ tty3270_sched_bh(tub_t *tubp)
if (tubp->flags & TUB_BHPENDING) if (tubp->flags & TUB_BHPENDING)
return; return;
tubp->flags |= TUB_BHPENDING; tubp->flags |= TUB_BHPENDING;
tubp->tqueue.routine = tty3270_bh; tasklet_init(&tubp->tasklet, tty3270_tasklet,
tubp->tqueue.data = tubp; (unsigned long) tubp);
queue_task(&tubp->tqueue, &tq_immediate); tasklet_schedule(&tubp->tasklet);
mark_bh(IMMEDIATE_BH);
} }
/* /*
......
...@@ -86,7 +86,7 @@ typedef struct { ...@@ -86,7 +86,7 @@ typedef struct {
wait_queue_head_t open_wait; wait_queue_head_t open_wait;
wait_queue_head_t close_wait; wait_queue_head_t close_wait;
struct semaphore write_sem; struct semaphore write_sem;
struct tq_struct tq; struct tasklet_struct tasklet;
struct timer_list stoptimer; struct timer_list stoptimer;
} ctc_tty_info; } ctc_tty_info;
...@@ -272,8 +272,7 @@ ctc_tty_netif_rx(struct sk_buff *skb) ...@@ -272,8 +272,7 @@ ctc_tty_netif_rx(struct sk_buff *skb)
*/ */
skb_queue_tail(&info->rx_queue, skb); skb_queue_tail(&info->rx_queue, skb);
/* Schedule dequeuing */ /* Schedule dequeuing */
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
static int static int
...@@ -390,8 +389,7 @@ ctc_tty_inject(ctc_tty_info *info, char c) ...@@ -390,8 +389,7 @@ ctc_tty_inject(ctc_tty_info *info, char c)
skb_reserve(skb, skb_res); skb_reserve(skb, skb_res);
*(skb_put(skb, 1)) = c; *(skb_put(skb, 1)) = c;
skb_queue_head(&info->tx_queue, skb); skb_queue_head(&info->tx_queue, skb);
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
static void static void
...@@ -400,8 +398,7 @@ ctc_tty_transmit_status(ctc_tty_info *info) ...@@ -400,8 +398,7 @@ ctc_tty_transmit_status(ctc_tty_info *info)
if (ctc_tty_shuttingdown) if (ctc_tty_shuttingdown)
return; return;
info->flags |= CTC_ASYNC_TX_LINESTAT; info->flags |= CTC_ASYNC_TX_LINESTAT;
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
static void static void
...@@ -562,8 +559,7 @@ ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int cou ...@@ -562,8 +559,7 @@ ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int cou
} }
if (skb_queue_len(&info->tx_queue)) { if (skb_queue_len(&info->tx_queue)) {
info->lsr &= ~UART_LSR_TEMT; info->lsr &= ~UART_LSR_TEMT;
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
if (from_user) if (from_user)
up(&info->write_sem); up(&info->write_sem);
...@@ -624,8 +620,7 @@ ctc_tty_flush_chars(struct tty_struct *tty) ...@@ -624,8 +620,7 @@ ctc_tty_flush_chars(struct tty_struct *tty)
return; return;
if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue))) if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
return; return;
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
/* /*
...@@ -1161,8 +1156,9 @@ ctc_tty_hangup(struct tty_struct *tty) ...@@ -1161,8 +1156,9 @@ ctc_tty_hangup(struct tty_struct *tty)
* the lower levels. * the lower levels.
*/ */
static void static void
ctc_tty_task(ctc_tty_info *info) ctc_tty_task(unsigned long arg)
{ {
ctc_tty_info *info = (void *)arg;
unsigned long saveflags; unsigned long saveflags;
int again; int again;
...@@ -1173,8 +1169,7 @@ ctc_tty_task(ctc_tty_info *info) ...@@ -1173,8 +1169,7 @@ ctc_tty_task(ctc_tty_info *info)
info->lsr |= UART_LSR_TEMT; info->lsr |= UART_LSR_TEMT;
again |= ctc_tty_readmodem(info); again |= ctc_tty_readmodem(info);
if (again) { if (again) {
queue_task(&info->tq, &tq_immediate); tasklet_schedule(&info->tasklet);
mark_bh(IMMEDIATE_BH);
} }
} }
spin_unlock_irqrestore(&ctc_tty_lock, saveflags); spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
...@@ -1234,14 +1229,8 @@ ctc_tty_init(void) ...@@ -1234,14 +1229,8 @@ ctc_tty_init(void)
for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) { for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
info = &driver->info[i]; info = &driver->info[i];
init_MUTEX(&info->write_sem); init_MUTEX(&info->write_sem);
#if LINUX_VERSION_CODE >= 0x020400 tasklet_init(&info->tasklet, ctc_tty_task,
INIT_LIST_HEAD(&info->tq.list); (unsigned long) info);
#else
info->tq.next = NULL;
#endif
info->tq.sync = 0;
info->tq.routine = (void *)(void *)ctc_tty_task;
info->tq.data = info;
info->magic = CTC_ASYNC_MAGIC; info->magic = CTC_ASYNC_MAGIC;
info->line = i; info->line = i;
info->tty = 0; info->tty = 0;
...@@ -1322,10 +1311,6 @@ ctc_tty_cleanup(int final) { ...@@ -1322,10 +1311,6 @@ ctc_tty_cleanup(int final) {
kfree(driver); kfree(driver);
driver = NULL; driver = NULL;
} else { } else {
int i;
for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
driver->info[i].tq.routine = NULL;
tty_unregister_driver(&driver->ctc_tty_device); tty_unregister_driver(&driver->ctc_tty_device);
} }
spin_unlock_irqrestore(&ctc_tty_lock, saveflags); spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
......
...@@ -41,9 +41,9 @@ ...@@ -41,9 +41,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include "iucv.h" #include "iucv.h"
#include <asm/io.h> #include <asm/io.h>
...@@ -99,16 +99,14 @@ typedef struct { ...@@ -99,16 +99,14 @@ typedef struct {
static struct list_head iucv_irq_queue; static struct list_head iucv_irq_queue;
static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED; static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED;
static struct tq_struct iucv_tq;
static atomic_t iucv_bh_scheduled = ATOMIC_INIT (0);
/* /*
*Internal function prototypes *Internal function prototypes
*/ */
static void iucv_bh_handler(void); static void iucv_tasklet_handler(unsigned long);
static void iucv_irq_handler(struct pt_regs *, __u16); static void iucv_irq_handler(struct pt_regs *, __u16);
static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0);
/************ FUNCTION ID'S ****************************/ /************ FUNCTION ID'S ****************************/
#define ACCEPT 10 #define ACCEPT 10
...@@ -385,11 +383,6 @@ iucv_init(void) ...@@ -385,11 +383,6 @@ iucv_init(void)
} }
memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE); memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
/* Initialize task queue */
INIT_LIST_HEAD(&iucv_tq.list);
iucv_tq.sync = 0;
iucv_tq.routine = (void *)iucv_bh_handler;
/* Initialize irq queue */ /* Initialize irq queue */
INIT_LIST_HEAD(&iucv_irq_queue); INIT_LIST_HEAD(&iucv_irq_queue);
...@@ -2177,7 +2170,7 @@ iucv_sever(__u16 pathid, __u8 user_data[16]) ...@@ -2177,7 +2170,7 @@ iucv_sever(__u16 pathid, __u8 user_data[16])
* @code: irq code * @code: irq code
* *
* Handles external interrupts coming in from CP. * Handles external interrupts coming in from CP.
* Places the interrupt buffer on a queue and schedules iucv_bh_handler(). * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler().
*/ */
static void static void
iucv_irq_handler(struct pt_regs *regs, __u16 code) iucv_irq_handler(struct pt_regs *regs, __u16 code)
...@@ -2200,10 +2193,7 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code) ...@@ -2200,10 +2193,7 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code)
list_add_tail(&irqdata->queue, &iucv_irq_queue); list_add_tail(&irqdata->queue, &iucv_irq_queue);
spin_unlock(&iucv_irq_queue_lock); spin_unlock(&iucv_irq_queue_lock);
if (atomic_compare_and_swap (0, 1, &iucv_bh_scheduled) == 0) { tasklet_schedule(&iucv_tasklet);
queue_task (&iucv_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
irq_exit(); irq_exit();
return; return;
...@@ -2214,7 +2204,7 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code) ...@@ -2214,7 +2204,7 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code)
* @int_buf: Pointer to copy of external interrupt buffer * @int_buf: Pointer to copy of external interrupt buffer
* *
* The workhorse for handling interrupts queued by iucv_irq_handler(). * The workhorse for handling interrupts queued by iucv_irq_handler().
* This function is called from the bottom half iucv_bh_handler(). * This function is called from the bottom half iucv_tasklet_handler().
*/ */
static void static void
iucv_do_int(iucv_GeneralInterrupt * int_buf) iucv_do_int(iucv_GeneralInterrupt * int_buf)
...@@ -2384,20 +2374,18 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) ...@@ -2384,20 +2374,18 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
} }
/** /**
* iucv_bh_handler: * iucv_tasklet_handler:
* *
* This function loops over the queue of irq buffers and runs iucv_do_int() * This function loops over the queue of irq buffers and runs iucv_do_int()
* on every queue element. * on every queue element.
*/ */
static void static void
iucv_bh_handler(void) iucv_tasklet_handler(unsigned long ignored)
{ {
struct list_head head; struct list_head head;
struct list_head *next; struct list_head *next;
ulong flags; ulong flags;
atomic_set(&iucv_bh_scheduled, 0);
spin_lock_irqsave(&iucv_irq_queue_lock, flags); spin_lock_irqsave(&iucv_irq_queue_lock, flags);
list_add(&head, &iucv_irq_queue); list_add(&head, &iucv_irq_queue);
list_del_init(&iucv_irq_queue); list_del_init(&iucv_irq_queue);
......
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