aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd.c22
-rw-r--r--drivers/s390/block/dasd_genhd.c1
-rw-r--r--drivers/s390/block/dasd_int.h1
3 files changed, 16 insertions, 8 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 5905936c7c60..56df3c5ed385 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -20,6 +20,7 @@
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/hdreg.h> 21#include <linux/hdreg.h>
22#include <linux/async.h> 22#include <linux/async.h>
23#include <linux/mutex.h>
23 24
24#include <asm/ccwdev.h> 25#include <asm/ccwdev.h>
25#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
@@ -112,6 +113,7 @@ struct dasd_device *dasd_alloc_device(void)
112 INIT_WORK(&device->restore_device, do_restore_device); 113 INIT_WORK(&device->restore_device, do_restore_device);
113 device->state = DASD_STATE_NEW; 114 device->state = DASD_STATE_NEW;
114 device->target = DASD_STATE_NEW; 115 device->target = DASD_STATE_NEW;
116 mutex_init(&device->state_mutex);
115 117
116 return device; 118 return device;
117} 119}
@@ -484,10 +486,8 @@ static void dasd_change_state(struct dasd_device *device)
484 if (rc) 486 if (rc)
485 device->target = device->state; 487 device->target = device->state;
486 488
487 if (device->state == device->target) { 489 if (device->state == device->target)
488 wake_up(&dasd_init_waitq); 490 wake_up(&dasd_init_waitq);
489 dasd_put_device(device);
490 }
491 491
492 /* let user-space know that the device status changed */ 492 /* let user-space know that the device status changed */
493 kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); 493 kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
@@ -502,7 +502,9 @@ static void dasd_change_state(struct dasd_device *device)
502static void do_kick_device(struct work_struct *work) 502static void do_kick_device(struct work_struct *work)
503{ 503{
504 struct dasd_device *device = container_of(work, struct dasd_device, kick_work); 504 struct dasd_device *device = container_of(work, struct dasd_device, kick_work);
505 mutex_lock(&device->state_mutex);
505 dasd_change_state(device); 506 dasd_change_state(device);
507 mutex_unlock(&device->state_mutex);
506 dasd_schedule_device_bh(device); 508 dasd_schedule_device_bh(device);
507 dasd_put_device(device); 509 dasd_put_device(device);
508} 510}
@@ -539,18 +541,19 @@ void dasd_restore_device(struct dasd_device *device)
539void dasd_set_target_state(struct dasd_device *device, int target) 541void dasd_set_target_state(struct dasd_device *device, int target)
540{ 542{
541 dasd_get_device(device); 543 dasd_get_device(device);
544 mutex_lock(&device->state_mutex);
542 /* If we are in probeonly mode stop at DASD_STATE_READY. */ 545 /* If we are in probeonly mode stop at DASD_STATE_READY. */
543 if (dasd_probeonly && target > DASD_STATE_READY) 546 if (dasd_probeonly && target > DASD_STATE_READY)
544 target = DASD_STATE_READY; 547 target = DASD_STATE_READY;
545 if (device->target != target) { 548 if (device->target != target) {
546 if (device->state == target) { 549 if (device->state == target)
547 wake_up(&dasd_init_waitq); 550 wake_up(&dasd_init_waitq);
548 dasd_put_device(device);
549 }
550 device->target = target; 551 device->target = target;
551 } 552 }
552 if (device->state != device->target) 553 if (device->state != device->target)
553 dasd_change_state(device); 554 dasd_change_state(device);
555 mutex_unlock(&device->state_mutex);
556 dasd_put_device(device);
554} 557}
555 558
556/* 559/*
@@ -1692,7 +1695,6 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
1692 cqr, rc); 1695 cqr, rc);
1693 } else { 1696 } else {
1694 cqr->stopclk = get_clock(); 1697 cqr->stopclk = get_clock();
1695 rc = 1;
1696 } 1698 }
1697 break; 1699 break;
1698 default: /* already finished or clear pending - do nothing */ 1700 default: /* already finished or clear pending - do nothing */
@@ -2170,9 +2172,13 @@ static void dasd_flush_request_queue(struct dasd_block *block)
2170static int dasd_open(struct block_device *bdev, fmode_t mode) 2172static int dasd_open(struct block_device *bdev, fmode_t mode)
2171{ 2173{
2172 struct dasd_block *block = bdev->bd_disk->private_data; 2174 struct dasd_block *block = bdev->bd_disk->private_data;
2173 struct dasd_device *base = block->base; 2175 struct dasd_device *base;
2174 int rc; 2176 int rc;
2175 2177
2178 if (!block)
2179 return -ENODEV;
2180
2181 base = block->base;
2176 atomic_inc(&block->open_count); 2182 atomic_inc(&block->open_count);
2177 if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { 2183 if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) {
2178 rc = -ENODEV; 2184 rc = -ENODEV;
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index d3198303b93c..94f92a1247f2 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -88,6 +88,7 @@ void dasd_gendisk_free(struct dasd_block *block)
88 if (block->gdp) { 88 if (block->gdp) {
89 del_gendisk(block->gdp); 89 del_gendisk(block->gdp);
90 block->gdp->queue = NULL; 90 block->gdp->queue = NULL;
91 block->gdp->private_data = NULL;
91 put_disk(block->gdp); 92 put_disk(block->gdp);
92 block->gdp = NULL; 93 block->gdp = NULL;
93 } 94 }
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index e4c2143dabf6..ed73ce550822 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -368,6 +368,7 @@ struct dasd_device {
368 368
369 /* Device state and target state. */ 369 /* Device state and target state. */
370 int state, target; 370 int state, target;
371 struct mutex state_mutex;
371 int stopped; /* device (ccw_device_start) was stopped */ 372 int stopped; /* device (ccw_device_start) was stopped */
372 373
373 /* reference count. */ 374 /* reference count. */