@@ -426,6 +426,31 @@ static ssize_t coredump_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_WO(coredump);
+static ssize_t coredump_disabled_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return scnprintf(buf, 3, "%d\n", dev->coredump_disabled);
+}
+
+static ssize_t coredump_disabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ long coredump_disabled;
+
+ if (!kstrtol(buf, 10, &coredump_disabled)) {
+ /* Consider any non-zero value as true */
+ if (coredump_disabled)
+ dev->coredump_disabled = true;
+ else
+ dev->coredump_disabled = false;
+ }
+
+ return count;
+}
+static DEVICE_ATTR_RW(coredump_disabled);
+
static int driver_sysfs_add(struct device *dev)
{
int ret;
@@ -448,9 +473,19 @@ static int driver_sysfs_add(struct device *dev)
return 0;
ret = device_create_file(dev, &dev_attr_coredump);
- if (!ret)
- return 0;
+ if (ret)
+ goto rm_driver;
+
+ ret = device_create_file(dev, &dev_attr_coredump_disabled);
+ if (ret)
+ goto rm_coredump;
+ return 0;
+
+rm_coredump:
+ device_remove_file(dev, &dev_attr_coredump);
+
+rm_driver:
sysfs_remove_link(&dev->kobj, "driver");
rm_dev:
@@ -466,8 +501,10 @@ static void driver_sysfs_remove(struct device *dev)
struct device_driver *drv = dev->driver;
if (drv) {
- if (drv->coredump)
+ if (drv->coredump) {
+ device_remove_file(dev, &dev_attr_coredump_disabled);
device_remove_file(dev, &dev_attr_coredump);
+ }
sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&dev->kobj, "driver");
}
@@ -255,7 +255,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
struct devcd_entry *devcd;
struct device *existing;
- if (devcd_disabled)
+ if (devcd_disabled || dev->coredump_disabled)
goto free;
existing = class_find_device(&devcd_class, NULL, dev,
@@ -469,6 +469,8 @@ struct device_physical_location {
* This identifies the device type and carries type-specific
* information.
* @mutex: Mutex to synchronize calls to its driver.
+ * @coredump_disabled: Can be used by drivers to selectively enable/disable the
+ * coredump for a particular device via sysfs entry.
* @bus: Type of bus device is on.
* @driver: Which driver has allocated this
* @platform_data: Platform data specific to the device.
@@ -561,6 +563,8 @@ struct device {
const char *init_name; /* initial name of the device */
const struct device_type *type;
+ bool coredump_disabled;
+
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */