summaryrefslogtreecommitdiffstats
path: root/lib/device/dev-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/device/dev-io.c')
-rw-r--r--lib/device/dev-io.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index 1995bdea..eb80a894 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -603,18 +603,40 @@ void dev_close_all(void)
}
}
+static inline int _dev_is_valid(struct device *dev)
+{
+ return (dev->max_error_count == NO_DEV_ERROR_COUNT_LIMIT ||
+ dev->error_count < dev->max_error_count);
+}
+
+static void _dev_inc_error_count(struct device *dev)
+{
+ if (++dev->error_count == dev->max_error_count)
+ log_warn("WARNING: Error counts reached a limit of %d. "
+ "Device %s was disabled",
+ dev->max_error_count, dev_name(dev));
+}
+
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
+ int ret;
if (!dev->open_count)
return_0;
+ if (!_dev_is_valid(dev))
+ return 0;
+
where.dev = dev;
where.start = offset;
where.size = len;
- return _aligned_io(&where, buffer, 0);
+ ret = _aligned_io(&where, buffer, 0);
+ if (!ret)
+ _dev_inc_error_count(dev);
+
+ return ret;
}
/*
@@ -670,17 +692,25 @@ int dev_append(struct device *dev, size_t len, void *buffer)
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
+ int ret;
if (!dev->open_count)
return_0;
+ if (!_dev_is_valid(dev))
+ return 0;
+
where.dev = dev;
where.start = offset;
where.size = len;
dev->flags |= DEV_ACCESSED_W;
- return _aligned_io(&where, buffer, 1);
+ ret = _aligned_io(&where, buffer, 1);
+ if (!ret)
+ _dev_inc_error_count(dev);
+
+ return ret;
}
int dev_set(struct device *dev, uint64_t offset, size_t len, int value)