diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 21 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 48 | ||||
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 3 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 3 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 3 | ||||
-rw-r--r-- | drivers/s390/char/Kconfig | 2 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 2 |
7 files changed, 77 insertions, 5 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 570ae59c1d5..bd591499414 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -336,6 +336,9 @@ static int dasd_state_ready_to_online(struct dasd_device * device) { int rc; + struct gendisk *disk; + struct disk_part_iter piter; + struct hd_struct *part; if (device->discipline->ready_to_online) { rc = device->discipline->ready_to_online(device); @@ -343,8 +346,14 @@ dasd_state_ready_to_online(struct dasd_device * device) return rc; } device->state = DASD_STATE_ONLINE; - if (device->block) + if (device->block) { dasd_schedule_block_bh(device->block); + disk = device->block->bdev->bd_disk; + disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0); + while ((part = disk_part_iter_next(&piter))) + kobject_uevent(&part_to_dev(part)->kobj, KOBJ_CHANGE); + disk_part_iter_exit(&piter); + } return 0; } @@ -354,6 +363,9 @@ dasd_state_ready_to_online(struct dasd_device * device) static int dasd_state_online_to_ready(struct dasd_device *device) { int rc; + struct gendisk *disk; + struct disk_part_iter piter; + struct hd_struct *part; if (device->discipline->online_to_ready) { rc = device->discipline->online_to_ready(device); @@ -361,6 +373,13 @@ static int dasd_state_online_to_ready(struct dasd_device *device) return rc; } device->state = DASD_STATE_READY; + if (device->block) { + disk = device->block->bdev->bd_disk; + disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0); + while ((part = disk_part_iter_next(&piter))) + kobject_uevent(&part_to_dev(part)->kobj, KOBJ_CHANGE); + disk_part_iter_exit(&piter); + } return 0; } diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 2ef25731d19..300e28a531f 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -206,6 +206,8 @@ dasd_feature_list(char *str, char **endp) features |= DASD_FEATURE_USEDIAG; else if (len == 6 && !strncmp(str, "erplog", 6)) features |= DASD_FEATURE_ERPLOG; + else if (len == 8 && !strncmp(str, "failfast", 8)) + features |= DASD_FEATURE_FAILFAST; else { MESSAGE(KERN_WARNING, "unsupported feature: %*s, " @@ -667,6 +669,51 @@ dasd_device_from_cdev(struct ccw_device *cdev) */ /* + * failfast controls the behaviour, if no path is available + */ +static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct dasd_devmap *devmap; + int ff_flag; + + devmap = dasd_find_busid(dev->bus_id); + if (!IS_ERR(devmap)) + ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; + else + ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0; + return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n"); +} + +static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dasd_devmap *devmap; + int val; + char *endp; + + devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); + if (IS_ERR(devmap)) + return PTR_ERR(devmap); + + val = simple_strtoul(buf, &endp, 0); + if (((endp + 1) < (buf + count)) || (val > 1)) + return -EINVAL; + + spin_lock(&dasd_devmap_lock); + if (val) + devmap->features |= DASD_FEATURE_FAILFAST; + else + devmap->features &= ~DASD_FEATURE_FAILFAST; + if (devmap->device) + devmap->device->features = devmap->features; + spin_unlock(&dasd_devmap_lock); + return count; +} + +static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store); + +/* * readonly controls the readonly status of a dasd */ static ssize_t @@ -1020,6 +1067,7 @@ static struct attribute * dasd_attrs[] = { &dev_attr_use_diag.attr, &dev_attr_eer_enabled.attr, &dev_attr_erplog.attr, + &dev_attr_failfast.attr, NULL, }; diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 7844461a995..ef2a5695205 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -544,7 +544,8 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, } cqr->retries = DIAG_MAX_RETRIES; cqr->buildclk = get_clock(); - if (blk_noretry_request(req)) + if (blk_noretry_request(req) || + block->base->features & DASD_FEATURE_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = memdev; cqr->memdev = memdev; diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index bd2c52e2076..bdb87998f36 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1700,7 +1700,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, recid++; } } - if (blk_noretry_request(req)) + if (blk_noretry_request(req) || + block->base->features & DASD_FEATURE_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = startdev; cqr->memdev = startdev; diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 7d442aeff3d..f1d17602169 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -355,7 +355,8 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, recid++; } } - if (blk_noretry_request(req)) + if (blk_noretry_request(req) || + block->base->features & DASD_FEATURE_FAILFAST) set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); cqr->startdev = memdev; cqr->memdev = memdev; diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index 643033890e3..0769ced52db 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig @@ -100,7 +100,7 @@ comment "S/390 tape interface support" config S390_TAPE_BLOCK bool "Support for tape block devices" - depends on S390_TAPE + depends on S390_TAPE && BLOCK help Select this option if you want to access your channel-attached tape devices using the block device interface. This interface is similar diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index f8a3b6967f6..da7afb04e71 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -169,6 +169,8 @@ static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) q->nr); debugfs_queues[i] = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR, debugfs_root, q, &debugfs_fops); + if (IS_ERR(debugfs_queues[i])) + debugfs_queues[i] = NULL; } void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) |