aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-09-22 16:58:34 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-09-22 16:58:41 -0400
commit255305536c1b56ad09590f1400fb2c788265e34e (patch)
tree23c97143b3ffe1598f76bc01b94407fa0c7d79d4 /drivers/s390/cio/css.c
parent2f17644d1cd0121daa0a997ff4eca5b3b44d1fae (diff)
[S390] cio: introduce css_eval_scheduled
Use css_eval_scheduled to determine if all scheduled subchannel evaluation is finished. Wait for this value to be 0 in the channel subsystem init function. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r--drivers/s390/cio/css.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 95805da2bb2..59c4b94cdb4 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -409,10 +409,14 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
409 409
410static struct idset *slow_subchannel_set; 410static struct idset *slow_subchannel_set;
411static spinlock_t slow_subchannel_lock; 411static spinlock_t slow_subchannel_lock;
412static wait_queue_head_t css_eval_wq;
413static atomic_t css_eval_scheduled;
412 414
413static int __init slow_subchannel_init(void) 415static int __init slow_subchannel_init(void)
414{ 416{
415 spin_lock_init(&slow_subchannel_lock); 417 spin_lock_init(&slow_subchannel_lock);
418 atomic_set(&css_eval_scheduled, 0);
419 init_waitqueue_head(&css_eval_wq);
416 slow_subchannel_set = idset_sch_new(); 420 slow_subchannel_set = idset_sch_new();
417 if (!slow_subchannel_set) { 421 if (!slow_subchannel_set) {
418 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n"); 422 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n");
@@ -468,9 +472,17 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
468 472
469static void css_slow_path_func(struct work_struct *unused) 473static void css_slow_path_func(struct work_struct *unused)
470{ 474{
475 unsigned long flags;
476
471 CIO_TRACE_EVENT(4, "slowpath"); 477 CIO_TRACE_EVENT(4, "slowpath");
472 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, 478 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn,
473 NULL); 479 NULL);
480 spin_lock_irqsave(&slow_subchannel_lock, flags);
481 if (idset_is_empty(slow_subchannel_set)) {
482 atomic_set(&css_eval_scheduled, 0);
483 wake_up(&css_eval_wq);
484 }
485 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
474} 486}
475 487
476static DECLARE_WORK(slow_path_work, css_slow_path_func); 488static DECLARE_WORK(slow_path_work, css_slow_path_func);
@@ -482,6 +494,7 @@ void css_schedule_eval(struct subchannel_id schid)
482 494
483 spin_lock_irqsave(&slow_subchannel_lock, flags); 495 spin_lock_irqsave(&slow_subchannel_lock, flags);
484 idset_sch_add(slow_subchannel_set, schid); 496 idset_sch_add(slow_subchannel_set, schid);
497 atomic_set(&css_eval_scheduled, 1);
485 queue_work(slow_path_wq, &slow_path_work); 498 queue_work(slow_path_wq, &slow_path_work);
486 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 499 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
487} 500}
@@ -492,6 +505,7 @@ void css_schedule_eval_all(void)
492 505
493 spin_lock_irqsave(&slow_subchannel_lock, flags); 506 spin_lock_irqsave(&slow_subchannel_lock, flags);
494 idset_fill(slow_subchannel_set); 507 idset_fill(slow_subchannel_set);
508 atomic_set(&css_eval_scheduled, 1);
495 queue_work(slow_path_wq, &slow_path_work); 509 queue_work(slow_path_wq, &slow_path_work);
496 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 510 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
497} 511}
@@ -1007,6 +1021,8 @@ static int __init channel_subsystem_init_sync(void)
1007{ 1021{
1008 /* Allocate and register subchannels. */ 1022 /* Allocate and register subchannels. */
1009 for_each_subchannel(setup_subchannel, NULL); 1023 for_each_subchannel(setup_subchannel, NULL);
1024 /* Wait for the evaluation of subchannels to finish. */
1025 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
1010 1026
1011 /* Wait for the initialization of ccw devices to finish. */ 1027 /* Wait for the initialization of ccw devices to finish. */
1012 wait_event(ccw_device_init_wq, 1028 wait_event(ccw_device_init_wq,