aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2009-04-14 09:36:23 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-04-14 09:37:25 -0400
commitf3445a1a656bc26b07946cc6d20de1ef07c8d116 (patch)
tree5ef9f40b00ac142d7f7c5cf0bdab77998a319165 /drivers/s390/block
parent75cb71f3184f3dd5b78d991d5e0e047774865f5d (diff)
[S390] dasd: Use the new async framework for autoonlining.
The dasd driver can automatically online detected dasds, which especially important for finding the root device. Currently, it will wait for each online operation to finish individually, which may take long if many dasds need to be onlined. When using the new async framework, these onlining operations can run in parallel and presence of the root device is ensured by the fact that prepare_namespace() waits for all async threads to finish. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0570794ccf1c..d1815272c435 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -20,6 +20,7 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/buffer_head.h> 21#include <linux/buffer_head.h>
22#include <linux/hdreg.h> 22#include <linux/hdreg.h>
23#include <linux/async.h>
23 24
24#include <asm/ccwdev.h> 25#include <asm/ccwdev.h>
25#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
@@ -480,8 +481,10 @@ static void dasd_change_state(struct dasd_device *device)
480 if (rc && rc != -EAGAIN) 481 if (rc && rc != -EAGAIN)
481 device->target = device->state; 482 device->target = device->state;
482 483
483 if (device->state == device->target) 484 if (device->state == device->target) {
484 wake_up(&dasd_init_waitq); 485 wake_up(&dasd_init_waitq);
486 dasd_put_device(device);
487 }
485 488
486 /* let user-space know that the device status changed */ 489 /* let user-space know that the device status changed */
487 kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); 490 kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
@@ -513,12 +516,15 @@ void dasd_kick_device(struct dasd_device *device)
513 */ 516 */
514void dasd_set_target_state(struct dasd_device *device, int target) 517void dasd_set_target_state(struct dasd_device *device, int target)
515{ 518{
519 dasd_get_device(device);
516 /* If we are in probeonly mode stop at DASD_STATE_READY. */ 520 /* If we are in probeonly mode stop at DASD_STATE_READY. */
517 if (dasd_probeonly && target > DASD_STATE_READY) 521 if (dasd_probeonly && target > DASD_STATE_READY)
518 target = DASD_STATE_READY; 522 target = DASD_STATE_READY;
519 if (device->target != target) { 523 if (device->target != target) {
520 if (device->state == target) 524 if (device->state == target) {
521 wake_up(&dasd_init_waitq); 525 wake_up(&dasd_init_waitq);
526 dasd_put_device(device);
527 }
522 device->target = target; 528 device->target = target;
523 } 529 }
524 if (device->state != device->target) 530 if (device->state != device->target)
@@ -2148,6 +2154,22 @@ dasd_exit(void)
2148 * SECTION: common functions for ccw_driver use 2154 * SECTION: common functions for ccw_driver use
2149 */ 2155 */
2150 2156
2157static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
2158{
2159 struct ccw_device *cdev = data;
2160 int ret;
2161
2162 ret = ccw_device_set_online(cdev);
2163 if (ret)
2164 pr_warning("%s: Setting the DASD online failed with rc=%d\n",
2165 dev_name(&cdev->dev), ret);
2166 else {
2167 struct dasd_device *device = dasd_device_from_cdev(cdev);
2168 wait_event(dasd_init_waitq, _wait_for_device(device));
2169 dasd_put_device(device);
2170 }
2171}
2172
2151/* 2173/*
2152 * Initial attempt at a probe function. this can be simplified once 2174 * Initial attempt at a probe function. this can be simplified once
2153 * the other detection code is gone. 2175 * the other detection code is gone.
@@ -2180,10 +2202,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
2180 */ 2202 */
2181 if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || 2203 if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
2182 (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0)) 2204 (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
2183 ret = ccw_device_set_online(cdev); 2205 async_schedule(dasd_generic_auto_online, cdev);
2184 if (ret)
2185 pr_warning("%s: Setting the DASD online failed with rc=%d\n",
2186 dev_name(&cdev->dev), ret);
2187 return 0; 2206 return 0;
2188} 2207}
2189 2208
@@ -2290,13 +2309,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
2290 } else 2309 } else
2291 pr_debug("dasd_generic device %s found\n", 2310 pr_debug("dasd_generic device %s found\n",
2292 dev_name(&cdev->dev)); 2311 dev_name(&cdev->dev));
2293
2294 /* FIXME: we have to wait for the root device but we don't want
2295 * to wait for each single device but for all at once. */
2296 wait_event(dasd_init_waitq, _wait_for_device(device));
2297
2298 dasd_put_device(device); 2312 dasd_put_device(device);
2299
2300 return rc; 2313 return rc;
2301} 2314}
2302 2315