mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	drivers: base: add coredump driver ops
This adds the coredump driver operation. When the driver defines it a coredump file is added in the sysfs folder of the device upon driver binding. The file is removed when the driver is unbound. User-space can trigger a coredump for this device by echo'ing to the coredump file. Signed-off-by: Arend van Spriel <aspriel@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									36d1d09af1
								
							
						
					
					
						commit
						3c47d19ff4
					
				
					 2 changed files with 34 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -288,6 +288,18 @@ static void driver_bound(struct device *dev)
 | 
			
		|||
	kobject_uevent(&dev->kobj, KOBJ_BIND);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t coredump_store(struct device *dev, struct device_attribute *attr,
 | 
			
		||||
			    const char *buf, size_t count)
 | 
			
		||||
{
 | 
			
		||||
	device_lock(dev);
 | 
			
		||||
	if (dev->driver->coredump)
 | 
			
		||||
		dev->driver->coredump(dev);
 | 
			
		||||
	device_unlock(dev);
 | 
			
		||||
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
static DEVICE_ATTR_WO(coredump);
 | 
			
		||||
 | 
			
		||||
static int driver_sysfs_add(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -297,14 +309,26 @@ static int driver_sysfs_add(struct device *dev)
 | 
			
		|||
					     BUS_NOTIFY_BIND_DRIVER, dev);
 | 
			
		||||
 | 
			
		||||
	ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
 | 
			
		||||
				kobject_name(&dev->kobj));
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto fail;
 | 
			
		||||
 | 
			
		||||
	ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
 | 
			
		||||
				"driver");
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto rm_dev;
 | 
			
		||||
 | 
			
		||||
	if (!IS_ENABLED(CONFIG_DEV_COREDUMP) || !dev->driver->coredump ||
 | 
			
		||||
	    !device_create_file(dev, &dev_attr_coredump))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	sysfs_remove_link(&dev->kobj, "driver");
 | 
			
		||||
 | 
			
		||||
rm_dev:
 | 
			
		||||
	sysfs_remove_link(&dev->driver->p->kobj,
 | 
			
		||||
			  kobject_name(&dev->kobj));
 | 
			
		||||
	if (ret == 0) {
 | 
			
		||||
		ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
 | 
			
		||||
					"driver");
 | 
			
		||||
		if (ret)
 | 
			
		||||
			sysfs_remove_link(&dev->driver->p->kobj,
 | 
			
		||||
					kobject_name(&dev->kobj));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -313,6 +337,8 @@ static void driver_sysfs_remove(struct device *dev)
 | 
			
		|||
	struct device_driver *drv = dev->driver;
 | 
			
		||||
 | 
			
		||||
	if (drv) {
 | 
			
		||||
		if (drv->coredump)
 | 
			
		||||
			device_remove_file(dev, &dev_attr_coredump);
 | 
			
		||||
		sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
 | 
			
		||||
		sysfs_remove_link(&dev->kobj, "driver");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -287,6 +287,7 @@ struct device_driver {
 | 
			
		|||
	const struct attribute_group **groups;
 | 
			
		||||
 | 
			
		||||
	const struct dev_pm_ops *pm;
 | 
			
		||||
	int (*coredump) (struct device *dev);
 | 
			
		||||
 | 
			
		||||
	struct driver_private *p;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +301,6 @@ extern struct device_driver *driver_find(const char *name,
 | 
			
		|||
extern int driver_probe_done(void);
 | 
			
		||||
extern void wait_for_device_probe(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* sysfs interface for exporting driver attributes */
 | 
			
		||||
 | 
			
		||||
struct driver_attribute {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue