diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 56 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 4 |
3 files changed, 62 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index b97624bf183d..54f4bb8060c1 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2894,6 +2894,8 @@ enum blk_eh_timer_return dasd_times_out(struct request *req) | |||
2894 | return BLK_EH_NOT_HANDLED; | 2894 | return BLK_EH_NOT_HANDLED; |
2895 | 2895 | ||
2896 | device = cqr->startdev ? cqr->startdev : block->base; | 2896 | device = cqr->startdev ? cqr->startdev : block->base; |
2897 | if (!device->blk_timeout) | ||
2898 | return BLK_EH_RESET_TIMER; | ||
2897 | DBF_DEV_EVENT(DBF_WARNING, device, | 2899 | DBF_DEV_EVENT(DBF_WARNING, device, |
2898 | " dasd_times_out cqr %p status %x", | 2900 | " dasd_times_out cqr %p status %x", |
2899 | cqr, cqr->status); | 2901 | cqr, cqr->status); |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index bc3e7afac18b..58bc6eb49de1 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -1280,6 +1280,61 @@ dasd_retries_store(struct device *dev, struct device_attribute *attr, | |||
1280 | 1280 | ||
1281 | static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store); | 1281 | static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store); |
1282 | 1282 | ||
1283 | static ssize_t | ||
1284 | dasd_timeout_show(struct device *dev, struct device_attribute *attr, | ||
1285 | char *buf) | ||
1286 | { | ||
1287 | struct dasd_device *device; | ||
1288 | int len; | ||
1289 | |||
1290 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1291 | if (IS_ERR(device)) | ||
1292 | return -ENODEV; | ||
1293 | len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout); | ||
1294 | dasd_put_device(device); | ||
1295 | return len; | ||
1296 | } | ||
1297 | |||
1298 | static ssize_t | ||
1299 | dasd_timeout_store(struct device *dev, struct device_attribute *attr, | ||
1300 | const char *buf, size_t count) | ||
1301 | { | ||
1302 | struct dasd_device *device; | ||
1303 | struct request_queue *q; | ||
1304 | unsigned long val, flags; | ||
1305 | |||
1306 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1307 | if (IS_ERR(device) || !device->block) | ||
1308 | return -ENODEV; | ||
1309 | |||
1310 | if ((strict_strtoul(buf, 10, &val) != 0) || | ||
1311 | val > UINT_MAX / HZ) { | ||
1312 | dasd_put_device(device); | ||
1313 | return -EINVAL; | ||
1314 | } | ||
1315 | q = device->block->request_queue; | ||
1316 | if (!q) { | ||
1317 | dasd_put_device(device); | ||
1318 | return -ENODEV; | ||
1319 | } | ||
1320 | spin_lock_irqsave(&device->block->request_queue_lock, flags); | ||
1321 | if (!val) | ||
1322 | blk_queue_rq_timed_out(q, NULL); | ||
1323 | else | ||
1324 | blk_queue_rq_timed_out(q, dasd_times_out); | ||
1325 | |||
1326 | device->blk_timeout = val; | ||
1327 | |||
1328 | blk_queue_rq_timeout(q, device->blk_timeout * HZ); | ||
1329 | spin_unlock_irqrestore(&device->block->request_queue_lock, flags); | ||
1330 | |||
1331 | dasd_put_device(device); | ||
1332 | return count; | ||
1333 | } | ||
1334 | |||
1335 | static DEVICE_ATTR(timeout, 0644, | ||
1336 | dasd_timeout_show, dasd_timeout_store); | ||
1337 | |||
1283 | static ssize_t dasd_reservation_policy_show(struct device *dev, | 1338 | static ssize_t dasd_reservation_policy_show(struct device *dev, |
1284 | struct device_attribute *attr, | 1339 | struct device_attribute *attr, |
1285 | char *buf) | 1340 | char *buf) |
@@ -1391,6 +1446,7 @@ static struct attribute * dasd_attrs[] = { | |||
1391 | &dev_attr_failfast.attr, | 1446 | &dev_attr_failfast.attr, |
1392 | &dev_attr_expires.attr, | 1447 | &dev_attr_expires.attr, |
1393 | &dev_attr_retries.attr, | 1448 | &dev_attr_retries.attr, |
1449 | &dev_attr_timeout.attr, | ||
1394 | &dev_attr_reservation_policy.attr, | 1450 | &dev_attr_reservation_policy.attr, |
1395 | &dev_attr_last_known_reservation_state.attr, | 1451 | &dev_attr_last_known_reservation_state.attr, |
1396 | &dev_attr_safe_offline.attr, | 1452 | &dev_attr_safe_offline.attr, |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index ad42075868c7..2bd03f45a72e 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -470,6 +470,8 @@ struct dasd_device { | |||
470 | unsigned long default_expires; | 470 | unsigned long default_expires; |
471 | unsigned long default_retries; | 471 | unsigned long default_retries; |
472 | 472 | ||
473 | unsigned long blk_timeout; | ||
474 | |||
473 | struct dentry *debugfs_dentry; | 475 | struct dentry *debugfs_dentry; |
474 | struct dasd_profile profile; | 476 | struct dasd_profile profile; |
475 | }; | 477 | }; |
@@ -663,6 +665,8 @@ void dasd_free_device(struct dasd_device *); | |||
663 | struct dasd_block *dasd_alloc_block(void); | 665 | struct dasd_block *dasd_alloc_block(void); |
664 | void dasd_free_block(struct dasd_block *); | 666 | void dasd_free_block(struct dasd_block *); |
665 | 667 | ||
668 | enum blk_eh_timer_return dasd_times_out(struct request *req); | ||
669 | |||
666 | void dasd_enable_device(struct dasd_device *); | 670 | void dasd_enable_device(struct dasd_device *); |
667 | void dasd_set_target_state(struct dasd_device *, int); | 671 | void dasd_set_target_state(struct dasd_device *, int); |
668 | void dasd_kick_device(struct dasd_device *); | 672 | void dasd_kick_device(struct dasd_device *); |