Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9f852df authored by Kay Sievers's avatar Kay Sievers Committed by Greg Kroah-Hartman
Browse files

Driver core: add device_type to struct device



This allows us to add type specific attributes, uevent vars and
release funtions.

A subsystem can carry different types of devices like the "block"
subsys has disks and partitions. Both types create a different set
of attributes, but belong to the same subsystem.

This corresponds to the low level objects:
  kobject   -> device       (object/device data)
  kobj_type -> device_type  (type of object/device we are embedded in)
  kset      -> class/bus    (list of objects/devices of a subsystem)

Signed-off-by: default avatarKay Sievers <kay.sievers@novell.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 239378f1
Loading
Loading
Loading
Loading
+39 −18
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)

	if (dev->release)
		dev->release(dev);
	else if (dev->type && dev->type->release)
		dev->type->release(dev);
	else if (dev->class && dev->class->dev_release)
		dev->class->dev_release(dev);
	else {
@@ -206,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
	if (dev->bus && dev->bus->uevent) {
		/* have the bus specific function add its stuff */
		retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
			if (retval) {
			pr_debug ("%s - uevent() returned %d\n",
		if (retval)
			pr_debug ("%s: bus uevent() returned %d\n",
				  __FUNCTION__, retval);
	}
	}

	if (dev->class && dev->class->dev_uevent) {
		/* have the class specific function add its stuff */
		retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
			if (retval) {
				pr_debug("%s - dev_uevent() returned %d\n",
		if (retval)
			pr_debug("%s: class uevent() returned %d\n",
				 __FUNCTION__, retval);
	}

	if (dev->type && dev->type->uevent) {
		/* have the device type specific fuction add its stuff */
		retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
		if (retval)
			pr_debug("%s: dev_type uevent() returned %d\n",
				 __FUNCTION__, retval);
	}

	return retval;
@@ -269,37 +277,50 @@ static void device_remove_groups(struct device *dev)
static int device_add_attrs(struct device *dev)
{
	struct class *class = dev->class;
	struct device_type *type = dev->type;
	int error = 0;
	int i;

	if (!class)
		return 0;

	if (class->dev_attrs) {
	if (class && class->dev_attrs) {
		for (i = 0; attr_name(class->dev_attrs[i]); i++) {
			error = device_create_file(dev, &class->dev_attrs[i]);
			if (error)
				break;
		}
	}
		if (error)
			while (--i >= 0)
				device_remove_file(dev, &class->dev_attrs[i]);
	}

	if (type && type->attrs) {
		for (i = 0; attr_name(type->attrs[i]); i++) {
			error = device_create_file(dev, &type->attrs[i]);
			if (error)
				break;
		}
		if (error)
			while (--i >= 0)
				device_remove_file(dev, &type->attrs[i]);
	}

	return error;
}

static void device_remove_attrs(struct device *dev)
{
	struct class *class = dev->class;
	struct device_type *type = dev->type;
	int i;

	if (!class)
		return;

	if (class->dev_attrs) {
	if (class && class->dev_attrs) {
		for (i = 0; attr_name(class->dev_attrs[i]); i++)
			device_remove_file(dev, &class->dev_attrs[i]);
	}

	if (type && type->attrs) {
		for (i = 0; attr_name(type->attrs[i]); i++)
			device_remove_file(dev, &type->attrs[i]);
	}
}


+2 −2
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@
#include <linux/hid.h>
#include "usbhid.h"

struct device_type {
struct dev_type {
	u16 idVendor;
	u16 idProduct;
	const signed short *ff;
@@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
	-1
};

static const struct device_type devices[] = {
static const struct dev_type devices[] = {
	{ 0x046d, 0xc211, ff_rumble },
	{ 0x046d, 0xc219, ff_rumble },
	{ 0x046d, 0xc283, ff_joystick },
+8 −0
Original line number Diff line number Diff line
@@ -328,6 +328,13 @@ extern struct class_device *class_device_create(struct class *cls,
					__attribute__((format(printf,5,6)));
extern void class_device_destroy(struct class *cls, dev_t devt);

struct device_type {
	struct device_attribute *attrs;
	int (*uevent)(struct device *dev, char **envp, int num_envp,
		      char *buffer, int buffer_size);
	void (*release)(struct device *dev);
};

/* interface for exporting device attributes */
struct device_attribute {
	struct attribute	attr;
@@ -356,6 +363,7 @@ struct device {

	struct kobject kobj;
	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
	struct device_type	*type;
	unsigned		is_registered:1;
	struct device_attribute uevent_attr;
	struct device_attribute *devt_attr;