diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-10-10 15:33:28 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-10-10 15:34:02 -0400 |
commit | 408aec3c6c3cb5b4774f96ea7a35cd15ee91a56f (patch) | |
tree | 4aef11c7b81216a0b76a61d2c920e07f3ce609f8 /drivers/s390 | |
parent | 2332ce1a97963b7769e0c2d40492a10a124efba5 (diff) |
[S390] 3215: Remove tasklet.
The 3215 console irq handler used to schedule a tasklet. However the
console irq handler also gets called from the infamous cio_tpi()
function. Which in turn does something like
local_bh_disable()
[call console irq handler]
_local_bh_enable()
_local_bh_enable() prevents execution of softirqs, which is intended
within cio_tpi(). However there might be a new softirq pending because
irq handler scheduled a tasklet.
In order to prevent this behaviour we just get rid of the tasklet.
It's not doing much anyway.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/con3215.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 982cf62ab66d..9ab06e0dad40 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -89,7 +89,6 @@ struct raw3215_info { | |||
89 | int count; /* number of bytes in output buffer */ | 89 | int count; /* number of bytes in output buffer */ |
90 | int written; /* number of bytes in write requests */ | 90 | int written; /* number of bytes in write requests */ |
91 | struct tty_struct *tty; /* pointer to tty structure if present */ | 91 | struct tty_struct *tty; /* pointer to tty structure if present */ |
92 | struct tasklet_struct tasklet; | ||
93 | struct raw3215_req *queued_read; /* pointer to queued read requests */ | 92 | struct raw3215_req *queued_read; /* pointer to queued read requests */ |
94 | struct raw3215_req *queued_write;/* pointer to queued write requests */ | 93 | struct raw3215_req *queued_write;/* pointer to queued write requests */ |
95 | wait_queue_head_t empty_wait; /* wait queue for flushing */ | 94 | wait_queue_head_t empty_wait; /* wait queue for flushing */ |
@@ -342,21 +341,14 @@ raw3215_try_io(struct raw3215_info *raw) | |||
342 | } | 341 | } |
343 | 342 | ||
344 | /* | 343 | /* |
345 | * The bottom half handler routine for 3215 devices. It tries to start | 344 | * Try to start the next IO and wake up processes waiting on the tty. |
346 | * the next IO and wakes up processes waiting on the tty. | ||
347 | */ | 345 | */ |
348 | static void | 346 | static void raw3215_next_io(struct raw3215_info *raw) |
349 | raw3215_tasklet(void *data) | ||
350 | { | 347 | { |
351 | struct raw3215_info *raw; | ||
352 | struct tty_struct *tty; | 348 | struct tty_struct *tty; |
353 | unsigned long flags; | ||
354 | 349 | ||
355 | raw = (struct raw3215_info *) data; | ||
356 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | ||
357 | raw3215_mk_write_req(raw); | 350 | raw3215_mk_write_req(raw); |
358 | raw3215_try_io(raw); | 351 | raw3215_try_io(raw); |
359 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | ||
360 | tty = raw->tty; | 352 | tty = raw->tty; |
361 | if (tty != NULL && | 353 | if (tty != NULL && |
362 | RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { | 354 | RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { |
@@ -381,7 +373,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
381 | cstat = irb->scsw.cmd.cstat; | 373 | cstat = irb->scsw.cmd.cstat; |
382 | dstat = irb->scsw.cmd.dstat; | 374 | dstat = irb->scsw.cmd.dstat; |
383 | if (cstat != 0) | 375 | if (cstat != 0) |
384 | tasklet_schedule(&raw->tasklet); | 376 | raw3215_next_io(raw); |
385 | if (dstat & 0x01) { /* we got a unit exception */ | 377 | if (dstat & 0x01) { /* we got a unit exception */ |
386 | dstat &= ~0x01; /* we can ignore it */ | 378 | dstat &= ~0x01; /* we can ignore it */ |
387 | } | 379 | } |
@@ -391,7 +383,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
391 | break; | 383 | break; |
392 | /* Attention interrupt, someone hit the enter key */ | 384 | /* Attention interrupt, someone hit the enter key */ |
393 | raw3215_mk_read_req(raw); | 385 | raw3215_mk_read_req(raw); |
394 | tasklet_schedule(&raw->tasklet); | 386 | raw3215_next_io(raw); |
395 | break; | 387 | break; |
396 | case 0x08: | 388 | case 0x08: |
397 | case 0x0C: | 389 | case 0x0C: |
@@ -449,7 +441,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
449 | raw->queued_read == NULL) { | 441 | raw->queued_read == NULL) { |
450 | wake_up_interruptible(&raw->empty_wait); | 442 | wake_up_interruptible(&raw->empty_wait); |
451 | } | 443 | } |
452 | tasklet_schedule(&raw->tasklet); | 444 | raw3215_next_io(raw); |
453 | break; | 445 | break; |
454 | default: | 446 | default: |
455 | /* Strange interrupt, I'll do my best to clean up */ | 447 | /* Strange interrupt, I'll do my best to clean up */ |
@@ -461,7 +453,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
461 | raw->flags &= ~RAW3215_WORKING; | 453 | raw->flags &= ~RAW3215_WORKING; |
462 | raw3215_free_req(req); | 454 | raw3215_free_req(req); |
463 | } | 455 | } |
464 | tasklet_schedule(&raw->tasklet); | 456 | raw3215_next_io(raw); |
465 | } | 457 | } |
466 | return; | 458 | return; |
467 | } | 459 | } |
@@ -675,9 +667,6 @@ raw3215_probe (struct ccw_device *cdev) | |||
675 | kfree(raw); | 667 | kfree(raw); |
676 | return -ENOMEM; | 668 | return -ENOMEM; |
677 | } | 669 | } |
678 | tasklet_init(&raw->tasklet, | ||
679 | (void (*)(unsigned long)) raw3215_tasklet, | ||
680 | (unsigned long) raw); | ||
681 | init_waitqueue_head(&raw->empty_wait); | 670 | init_waitqueue_head(&raw->empty_wait); |
682 | 671 | ||
683 | cdev->dev.driver_data = raw; | 672 | cdev->dev.driver_data = raw; |
@@ -863,9 +852,6 @@ con3215_init(void) | |||
863 | cdev->handler = raw3215_irq; | 852 | cdev->handler = raw3215_irq; |
864 | 853 | ||
865 | raw->flags |= RAW3215_FIXED; | 854 | raw->flags |= RAW3215_FIXED; |
866 | tasklet_init(&raw->tasklet, | ||
867 | (void (*)(unsigned long)) raw3215_tasklet, | ||
868 | (unsigned long) raw); | ||
869 | init_waitqueue_head(&raw->empty_wait); | 855 | init_waitqueue_head(&raw->empty_wait); |
870 | 856 | ||
871 | /* Request the console irq */ | 857 | /* Request the console irq */ |