From 2e1314571feb1fd9aa4324df5fc43ccfd5ff75ec Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 26 Feb 2010 22:37:46 +0100 Subject: [PATCH] --- yaml --- r: 182179 b: refs/heads/master c: 9eb251225ab4dbea3119cfcf4c5194eed223a740 h: refs/heads/master i: 182177: 3bb85db44bc6546b12f9bb50bc34fee6aad5030c 182175: a7d01b33a1c331bc176f31c47db11da7baf275d7 v: v3 --- [refs] | 2 +- trunk/drivers/s390/block/dasd.c | 22 ++++++++++++++-------- trunk/drivers/s390/block/dasd_genhd.c | 1 + trunk/drivers/s390/block/dasd_int.h | 1 + 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 7a71ee61e67f..dbd217a0e640 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 22e0a0467292222214d1974d9bc2664a6c05980d +refs/heads/master: 9eb251225ab4dbea3119cfcf4c5194eed223a740 diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 5905936c7c60..56df3c5ed385 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -112,6 +113,7 @@ struct dasd_device *dasd_alloc_device(void) INIT_WORK(&device->restore_device, do_restore_device); device->state = DASD_STATE_NEW; device->target = DASD_STATE_NEW; + mutex_init(&device->state_mutex); return device; } @@ -484,10 +486,8 @@ static void dasd_change_state(struct dasd_device *device) if (rc) device->target = device->state; - if (device->state == device->target) { + if (device->state == device->target) wake_up(&dasd_init_waitq); - dasd_put_device(device); - } /* let user-space know that the device status changed */ kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); @@ -502,7 +502,9 @@ static void dasd_change_state(struct dasd_device *device) static void do_kick_device(struct work_struct *work) { struct dasd_device *device = container_of(work, struct dasd_device, kick_work); + mutex_lock(&device->state_mutex); dasd_change_state(device); + mutex_unlock(&device->state_mutex); dasd_schedule_device_bh(device); dasd_put_device(device); } @@ -539,18 +541,19 @@ void dasd_restore_device(struct dasd_device *device) void dasd_set_target_state(struct dasd_device *device, int target) { dasd_get_device(device); + mutex_lock(&device->state_mutex); /* If we are in probeonly mode stop at DASD_STATE_READY. */ if (dasd_probeonly && target > DASD_STATE_READY) target = DASD_STATE_READY; if (device->target != target) { - if (device->state == target) { + if (device->state == target) wake_up(&dasd_init_waitq); - dasd_put_device(device); - } device->target = target; } if (device->state != device->target) dasd_change_state(device); + mutex_unlock(&device->state_mutex); + dasd_put_device(device); } /* @@ -1692,7 +1695,6 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr) cqr, rc); } else { cqr->stopclk = get_clock(); - rc = 1; } break; default: /* already finished or clear pending - do nothing */ @@ -2170,9 +2172,13 @@ static void dasd_flush_request_queue(struct dasd_block *block) static int dasd_open(struct block_device *bdev, fmode_t mode) { struct dasd_block *block = bdev->bd_disk->private_data; - struct dasd_device *base = block->base; + struct dasd_device *base; int rc; + if (!block) + return -ENODEV; + + base = block->base; atomic_inc(&block->open_count); if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { rc = -ENODEV; diff --git a/trunk/drivers/s390/block/dasd_genhd.c b/trunk/drivers/s390/block/dasd_genhd.c index d3198303b93c..94f92a1247f2 100644 --- a/trunk/drivers/s390/block/dasd_genhd.c +++ b/trunk/drivers/s390/block/dasd_genhd.c @@ -88,6 +88,7 @@ void dasd_gendisk_free(struct dasd_block *block) if (block->gdp) { del_gendisk(block->gdp); block->gdp->queue = NULL; + block->gdp->private_data = NULL; put_disk(block->gdp); block->gdp = NULL; } diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index e4c2143dabf6..ed73ce550822 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -368,6 +368,7 @@ struct dasd_device { /* Device state and target state. */ int state, target; + struct mutex state_mutex; int stopped; /* device (ccw_device_start) was stopped */ /* reference count. */