From d282ed9b31386e50f20d2e6df16db33c76d398fb Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 26 Feb 2010 22:37:26 +0100 Subject: [PATCH] --- yaml --- r: 182159 b: refs/heads/master c: b4563e891a043fe521e62f6f621b928641474ff3 h: refs/heads/master i: 182157: 9e9cd909cac704b71ac63b36b40a7d99904ed6db 182155: 45196fa1c44c97f7794b3c161054e37356bdbfc8 182151: 6e7f6d177ee55b1f0e9d07e92d8aaa04120beded 182143: 445932772394e8bed69f4e733f6ad7bde85e1632 v: v3 --- [refs] | 2 +- trunk/arch/s390/include/asm/crw.h | 1 + trunk/drivers/s390/cio/crw.c | 29 +++++++++++++++-------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 6ea64e635ea0..ec2441079050 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 879acca58a904c25487c89ab11e23eb556fb13d3 +refs/heads/master: b4563e891a043fe521e62f6f621b928641474ff3 diff --git a/trunk/arch/s390/include/asm/crw.h b/trunk/arch/s390/include/asm/crw.h index 2185a6d619d3..749a97e61bea 100644 --- a/trunk/arch/s390/include/asm/crw.h +++ b/trunk/arch/s390/include/asm/crw.h @@ -32,6 +32,7 @@ typedef void (*crw_handler_t)(struct crw *, struct crw *, int); extern int crw_register_handler(int rsc, crw_handler_t handler); extern void crw_unregister_handler(int rsc); extern void crw_handle_channel_report(void); +void crw_wait_for_channel_report(void); #define NR_RSCS 16 diff --git a/trunk/drivers/s390/cio/crw.c b/trunk/drivers/s390/cio/crw.c index d157665d0e76..425f741a280c 100644 --- a/trunk/drivers/s390/cio/crw.c +++ b/trunk/drivers/s390/cio/crw.c @@ -8,15 +8,16 @@ * Heiko Carstens , */ -#include #include #include #include +#include #include -static struct semaphore crw_semaphore; static DEFINE_MUTEX(crw_handler_mutex); static crw_handler_t crw_handlers[NR_RSCS]; +static atomic_t crw_nr_req = ATOMIC_INIT(0); +static DECLARE_WAIT_QUEUE_HEAD(crw_handler_wait_q); /** * crw_register_handler() - register a channel report word handler @@ -59,12 +60,14 @@ void crw_unregister_handler(int rsc) static int crw_collect_info(void *unused) { struct crw crw[2]; - int ccode; + int ccode, signal; unsigned int chain; - int ignore; repeat: - ignore = down_interruptible(&crw_semaphore); + signal = wait_event_interruptible(crw_handler_wait_q, + atomic_read(&crw_nr_req) > 0); + if (unlikely(signal)) + atomic_inc(&crw_nr_req); chain = 0; while (1) { crw_handler_t handler; @@ -122,25 +125,23 @@ static int crw_collect_info(void *unused) /* chain is always 0 or 1 here. */ chain = crw[chain].chn ? chain + 1 : 0; } + if (atomic_dec_and_test(&crw_nr_req)) + wake_up(&crw_handler_wait_q); goto repeat; return 0; } void crw_handle_channel_report(void) { - up(&crw_semaphore); + atomic_inc(&crw_nr_req); + wake_up(&crw_handler_wait_q); } -/* - * Separate initcall needed for semaphore initialization since - * crw_handle_channel_report might be called before crw_machine_check_init. - */ -static int __init crw_init_semaphore(void) +void crw_wait_for_channel_report(void) { - init_MUTEX_LOCKED(&crw_semaphore); - return 0; + crw_handle_channel_report(); + wait_event(crw_handler_wait_q, atomic_read(&crw_nr_req) == 0); } -pure_initcall(crw_init_semaphore); /* * Machine checks for the channel subsystem must be enabled