diff options
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 8373ca0de8e0..fb613d70c2cb 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -21,7 +21,6 @@ #include <linux/hdreg.h> #include <linux/async.h> #include <linux/mutex.h> -#include <linux/smp_lock.h> #include <asm/ccwdev.h> #include <asm/ebcdic.h> @@ -1100,16 +1099,30 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, cqr = (struct dasd_ccw_req *) intparm; if (!cqr || ((scsw_cc(&irb->scsw) == 1) && (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && - (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) { + ((scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND) || + (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND | + SCSW_STCTL_ALERT_STATUS))))) { if (cqr && cqr->status == DASD_CQR_IN_IO) cqr->status = DASD_CQR_QUEUED; + if (cqr) + memcpy(&cqr->irb, irb, sizeof(*irb)); device = dasd_device_from_cdev_locked(cdev); - if (!IS_ERR(device)) { - dasd_device_clear_timer(device); - device->discipline->handle_unsolicited_interrupt(device, - irb); + if (IS_ERR(device)) + return; + /* ignore unsolicited interrupts for DIAG discipline */ + if (device->discipline == dasd_diag_discipline_pointer) { dasd_put_device(device); + return; } + device->discipline->dump_sense_dbf(device, irb, + "unsolicited"); + if ((device->features & DASD_FEATURE_ERPLOG)) + device->discipline->dump_sense(device, cqr, + irb); + dasd_device_clear_timer(device); + device->discipline->handle_unsolicited_interrupt(device, + irb); + dasd_put_device(device); return; } @@ -2197,7 +2210,6 @@ static void dasd_setup_queue(struct dasd_block *block) */ blk_queue_max_segment_size(block->request_queue, PAGE_SIZE); blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1); - blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN); } /* @@ -2236,7 +2248,6 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) if (!block) return -ENODEV; - lock_kernel(); base = block->base; atomic_inc(&block->open_count); if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { @@ -2271,14 +2282,12 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) goto out; } - unlock_kernel(); return 0; out: module_put(base->discipline->owner); unlock: atomic_dec(&block->open_count); - unlock_kernel(); return rc; } @@ -2286,10 +2295,8 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) { struct dasd_block *block = disk->private_data; - lock_kernel(); atomic_dec(&block->open_count); module_put(block->base->discipline->owner); - unlock_kernel(); return 0; } |