aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-01-30 04:26:18 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-07-01 11:31:25 -0400
commit3d71ad32167c9124d5621b54c37a74ef38aa93b0 (patch)
treef9f5eb8ff804adc07c72b337e0743580bbd4bdcc /drivers/s390
parent80bd7181b036c7b4118eb19cfff3b555889596e6 (diff)
s390/dasd: Add 'timeout' attribute
This patch adds a 'timeout' attibute to the DASD driver. When set to non-zero, the blk_timeout function will be enabled with the timeout specified in the attribute. Setting 'timeout' to '0' will disable block timeouts. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c2
-rw-r--r--drivers/s390/block/dasd_devmap.c56
-rw-r--r--drivers/s390/block/dasd_int.h4
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
1281static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store); 1281static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store);
1282 1282
1283static ssize_t
1284dasd_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
1298static ssize_t
1299dasd_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
1335static DEVICE_ATTR(timeout, 0644,
1336 dasd_timeout_show, dasd_timeout_store);
1337
1283static ssize_t dasd_reservation_policy_show(struct device *dev, 1338static 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 *);
663struct dasd_block *dasd_alloc_block(void); 665struct dasd_block *dasd_alloc_block(void);
664void dasd_free_block(struct dasd_block *); 666void dasd_free_block(struct dasd_block *);
665 667
668enum blk_eh_timer_return dasd_times_out(struct request *req);
669
666void dasd_enable_device(struct dasd_device *); 670void dasd_enable_device(struct dasd_device *);
667void dasd_set_target_state(struct dasd_device *, int); 671void dasd_set_target_state(struct dasd_device *, int);
668void dasd_kick_device(struct dasd_device *); 672void dasd_kick_device(struct dasd_device *);