diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd.c | 22 | ||||
-rw-r--r-- | drivers/s390/block/dasd_genhd.c | 1 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 |
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) | |||
502 | static void do_kick_device(struct work_struct *work) | 502 | static 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) | |||
539 | void dasd_set_target_state(struct dasd_device *device, int target) | 541 | void 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) | |||
2170 | static int dasd_open(struct block_device *bdev, fmode_t mode) | 2172 | static 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. */ |