class.c 15.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * class.c - basic device class management
 *
 * Copyright (c) 2002-3 Patrick Mochel
 * Copyright (c) 2002-3 Open Source Development Labs
 * Copyright (c) 2003-2004 Greg Kroah-Hartman
 * Copyright (c) 2003-2004 IBM Corp.
 *
 * This file is released under the GPLv2
 *
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
18
#include <linux/err.h>
T
Tim Schmielau 已提交
19
#include <linux/slab.h>
20
#include <linux/genhd.h>
21
#include <linux/mutex.h>
L
Linus Torvalds 已提交
22 23 24 25
#include "base.h"

#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)

26 27
static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
			       char *buf)
L
Linus Torvalds 已提交
28
{
29
	struct class_attribute *class_attr = to_class_attr(attr);
30
	struct subsys_private *cp = to_subsys_private(kobj);
31
	ssize_t ret = -EIO;
L
Linus Torvalds 已提交
32 33

	if (class_attr->show)
34
		ret = class_attr->show(cp->class, class_attr, buf);
L
Linus Torvalds 已提交
35 36 37
	return ret;
}

38 39
static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
				const char *buf, size_t count)
L
Linus Torvalds 已提交
40
{
41
	struct class_attribute *class_attr = to_class_attr(attr);
42
	struct subsys_private *cp = to_subsys_private(kobj);
43
	ssize_t ret = -EIO;
L
Linus Torvalds 已提交
44 45

	if (class_attr->store)
46
		ret = class_attr->store(cp->class, class_attr, buf, count);
L
Linus Torvalds 已提交
47 48 49
	return ret;
}

50 51 52 53 54 55 56 57 58 59 60 61
static const void *class_attr_namespace(struct kobject *kobj,
					const struct attribute *attr)
{
	struct class_attribute *class_attr = to_class_attr(attr);
	struct subsys_private *cp = to_subsys_private(kobj);
	const void *ns = NULL;

	if (class_attr->namespace)
		ns = class_attr->namespace(cp->class, class_attr);
	return ns;
}

62
static void class_release(struct kobject *kobj)
L
Linus Torvalds 已提交
63
{
64
	struct subsys_private *cp = to_subsys_private(kobj);
65
	struct class *class = cp->class;
L
Linus Torvalds 已提交
66 67 68 69 70 71 72 73

	pr_debug("class '%s': release.\n", class->name);

	if (class->class_release)
		class->class_release(class);
	else
		pr_debug("class '%s' does not have a release() function, "
			 "be careful\n", class->name);
74 75

	kfree(cp);
L
Linus Torvalds 已提交
76 77
}

78 79
static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj)
{
80
	struct subsys_private *cp = to_subsys_private(kobj);
81 82 83 84 85
	struct class *class = cp->class;

	return class->ns_type;
}

86
static const struct sysfs_ops class_sysfs_ops = {
87 88 89
	.show	   = class_attr_show,
	.store	   = class_attr_store,
	.namespace = class_attr_namespace,
L
Linus Torvalds 已提交
90 91
};

92
static struct kobj_type class_ktype = {
L
Linus Torvalds 已提交
93 94
	.sysfs_ops	= &class_sysfs_ops,
	.release	= class_release,
95
	.child_ns_type	= class_child_ns_type,
L
Linus Torvalds 已提交
96 97
};

98
/* Hotplug events for classes go to the class subsys */
99
static struct kset *class_kset;
L
Linus Torvalds 已提交
100 101


102
int class_create_file(struct class *cls, const struct class_attribute *attr)
L
Linus Torvalds 已提交
103 104
{
	int error;
105
	if (cls)
106
		error = sysfs_create_file(&cls->p->subsys.kobj,
107
					  &attr->attr);
108
	else
L
Linus Torvalds 已提交
109 110 111 112
		error = -EINVAL;
	return error;
}

113
void class_remove_file(struct class *cls, const struct class_attribute *attr)
L
Linus Torvalds 已提交
114 115
{
	if (cls)
116
		sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr);
L
Linus Torvalds 已提交
117 118
}

119
static struct class *class_get(struct class *cls)
L
Linus Torvalds 已提交
120 121
{
	if (cls)
122
		kset_get(&cls->p->subsys);
123
	return cls;
L
Linus Torvalds 已提交
124 125
}

126
static void class_put(struct class *cls)
L
Linus Torvalds 已提交
127
{
128
	if (cls)
129
		kset_put(&cls->p->subsys);
L
Linus Torvalds 已提交
130 131
}

132
static int add_class_attrs(struct class *cls)
L
Linus Torvalds 已提交
133 134 135 136 137 138
{
	int i;
	int error = 0;

	if (cls->class_attrs) {
		for (i = 0; attr_name(cls->class_attrs[i]); i++) {
139
			error = class_create_file(cls, &cls->class_attrs[i]);
L
Linus Torvalds 已提交
140
			if (error)
141
				goto error;
L
Linus Torvalds 已提交
142 143
		}
	}
144
done:
L
Linus Torvalds 已提交
145
	return error;
146
error:
L
Linus Torvalds 已提交
147
	while (--i >= 0)
148 149
		class_remove_file(cls, &cls->class_attrs[i]);
	goto done;
L
Linus Torvalds 已提交
150 151
}

152
static void remove_class_attrs(struct class *cls)
L
Linus Torvalds 已提交
153 154 155 156 157
{
	int i;

	if (cls->class_attrs) {
		for (i = 0; attr_name(cls->class_attrs[i]); i++)
158
			class_remove_file(cls, &cls->class_attrs[i]);
L
Linus Torvalds 已提交
159 160 161
	}
}

162 163 164 165 166 167 168 169 170 171 172 173 174 175
static void klist_class_dev_get(struct klist_node *n)
{
	struct device *dev = container_of(n, struct device, knode_class);

	get_device(dev);
}

static void klist_class_dev_put(struct klist_node *n)
{
	struct device *dev = container_of(n, struct device, knode_class);

	put_device(dev);
}

176
int __class_register(struct class *cls, struct lock_class_key *key)
L
Linus Torvalds 已提交
177
{
178
	struct subsys_private *cp;
L
Linus Torvalds 已提交
179 180 181 182
	int error;

	pr_debug("device class '%s': registering\n", cls->name);

183 184 185
	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
	if (!cp)
		return -ENOMEM;
186
	klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
187
	INIT_LIST_HEAD(&cp->interfaces);
188
	kset_init(&cp->glue_dirs);
189
	__mutex_init(&cp->mutex, "subsys mutex", key);
190
	error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
191 192
	if (error) {
		kfree(cp);
L
Linus Torvalds 已提交
193
		return error;
194
	}
L
Linus Torvalds 已提交
195

196 197 198 199
	/* set the default /sys/dev directory for devices of this class */
	if (!cls->dev_kobj)
		cls->dev_kobj = sysfs_dev_char_kobj;

200
#if defined(CONFIG_BLOCK)
201
	/* let the block class directory show up in the root of sysfs */
202
	if (!sysfs_deprecated || cls != &block_class)
203
		cp->subsys.kobj.kset = class_kset;
204
#else
205
	cp->subsys.kobj.kset = class_kset;
206
#endif
207
	cp->subsys.kobj.ktype = &class_ktype;
208 209
	cp->class = cls;
	cls->p = cp;
L
Linus Torvalds 已提交
210

211
	error = kset_register(&cp->subsys);
212 213 214
	if (error) {
		kfree(cp);
		return error;
L
Linus Torvalds 已提交
215
	}
216 217
	error = add_class_attrs(class_get(cls));
	class_put(cls);
L
Linus Torvalds 已提交
218 219
	return error;
}
220
EXPORT_SYMBOL_GPL(__class_register);
L
Linus Torvalds 已提交
221

222
void class_unregister(struct class *cls)
L
Linus Torvalds 已提交
223 224 225
{
	pr_debug("device class '%s': unregistering\n", cls->name);
	remove_class_attrs(cls);
226
	kset_unregister(&cls->p->subsys);
L
Linus Torvalds 已提交
227 228
}

229 230
static void class_create_release(struct class *cls)
{
231
	pr_debug("%s called for %s\n", __func__, cls->name);
232 233 234
	kfree(cls);
}

235 236 237 238
/**
 * class_create - create a struct class structure
 * @owner: pointer to the module that is to "own" this struct class
 * @name: pointer to a string for the name of this class.
239
 * @key: the lock_class_key for this class; used by mutex lock debugging
240 241
 *
 * This is used to create a struct class pointer that can then be used
242
 * in calls to device_create().
243
 *
244 245
 * Returns &struct class pointer on success, or ERR_PTR() on error.
 *
246 247 248
 * Note, the pointer created here is to be destroyed when finished by
 * making a call to class_destroy().
 */
249 250
struct class *__class_create(struct module *owner, const char *name,
			     struct lock_class_key *key)
251 252 253 254
{
	struct class *cls;
	int retval;

255
	cls = kzalloc(sizeof(*cls), GFP_KERNEL);
256 257 258 259 260 261 262 263 264
	if (!cls) {
		retval = -ENOMEM;
		goto error;
	}

	cls->name = name;
	cls->owner = owner;
	cls->class_release = class_create_release;

265
	retval = __class_register(cls, key);
266 267 268 269 270 271 272 273 274
	if (retval)
		goto error;

	return cls;

error:
	kfree(cls);
	return ERR_PTR(retval);
}
275
EXPORT_SYMBOL_GPL(__class_create);
276

277 278
/**
 * class_destroy - destroys a struct class structure
279
 * @cls: pointer to the struct class that is to be destroyed
280 281 282 283
 *
 * Note, the pointer to be destroyed must have been created with a call
 * to class_create().
 */
284 285 286 287 288 289 290
void class_destroy(struct class *cls)
{
	if ((cls == NULL) || (IS_ERR(cls)))
		return;

	class_unregister(cls);
}
L
Linus Torvalds 已提交
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
/**
 * class_dev_iter_init - initialize class device iterator
 * @iter: class iterator to initialize
 * @class: the class we wanna iterate over
 * @start: the device to start iterating from, if any
 * @type: device_type of the devices to iterate over, NULL for all
 *
 * Initialize class iterator @iter such that it iterates over devices
 * of @class.  If @start is set, the list iteration will start there,
 * otherwise if it is NULL, the iteration starts at the beginning of
 * the list.
 */
void class_dev_iter_init(struct class_dev_iter *iter, struct class *class,
			 struct device *start, const struct device_type *type)
{
	struct klist_node *start_knode = NULL;

	if (start)
		start_knode = &start->knode_class;
311
	klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode);
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
	iter->type = type;
}
EXPORT_SYMBOL_GPL(class_dev_iter_init);

/**
 * class_dev_iter_next - iterate to the next device
 * @iter: class iterator to proceed
 *
 * Proceed @iter to the next device and return it.  Returns NULL if
 * iteration is complete.
 *
 * The returned device is referenced and won't be released till
 * iterator is proceed to the next device or exited.  The caller is
 * free to do whatever it wants to do with the device including
 * calling back into class code.
 */
struct device *class_dev_iter_next(struct class_dev_iter *iter)
{
	struct klist_node *knode;
	struct device *dev;

	while (1) {
		knode = klist_next(&iter->ki);
		if (!knode)
			return NULL;
		dev = container_of(knode, struct device, knode_class);
		if (!iter->type || iter->type == dev->type)
			return dev;
	}
}
EXPORT_SYMBOL_GPL(class_dev_iter_next);

/**
 * class_dev_iter_exit - finish iteration
 * @iter: class iterator to finish
 *
 * Finish an iteration.  Always call this function after iteration is
 * complete whether the iteration ran till the end or not.
 */
void class_dev_iter_exit(struct class_dev_iter *iter)
{
	klist_iter_exit(&iter->ki);
}
EXPORT_SYMBOL_GPL(class_dev_iter_exit);

357 358 359
/**
 * class_for_each_device - device iterator
 * @class: the class we're iterating
360
 * @start: the device to start with in the list, if any.
361 362 363 364
 * @data: data for the callback
 * @fn: function to be called for each device
 *
 * Iterate over @class's list of devices, and call @fn for each,
365 366 367
 * passing it @data.  If @start is set, the list iteration will start
 * there, otherwise if it is NULL, the iteration starts at the
 * beginning of the list.
368 369 370 371
 *
 * We check the return of @fn each time. If it returns anything
 * other than 0, we break out and return that value.
 *
372 373
 * @fn is allowed to do anything including calling back into class
 * code.  There's no locking restriction.
374
 */
375 376
int class_for_each_device(struct class *class, struct device *start,
			  void *data, int (*fn)(struct device *, void *))
377
{
378
	struct class_dev_iter iter;
379 380 381 382 383
	struct device *dev;
	int error = 0;

	if (!class)
		return -EINVAL;
384 385 386 387 388 389
	if (!class->p) {
		WARN(1, "%s called for class '%s' before it was initialized",
		     __func__, class->name);
		return -EINVAL;
	}

390 391
	class_dev_iter_init(&iter, class, start, NULL);
	while ((dev = class_dev_iter_next(&iter))) {
392
		error = fn(dev, data);
393 394 395
		if (error)
			break;
	}
396
	class_dev_iter_exit(&iter);
397 398 399 400 401 402 403 404

	return error;
}
EXPORT_SYMBOL_GPL(class_for_each_device);

/**
 * class_find_device - device iterator for locating a particular device
 * @class: the class we're iterating
405
 * @start: Device to begin with
406 407 408 409 410 411 412 413 414 415
 * @data: data for the match function
 * @match: function to check device
 *
 * This is similar to the class_for_each_dev() function above, but it
 * returns a reference to a device that is 'found' for later use, as
 * determined by the @match callback.
 *
 * The callback should return 0 if the device doesn't match and non-zero
 * if it does.  If the callback returns non-zero, this function will
 * return to the caller and not iterate over any more devices.
416
 *
417 418
 * Note, you will need to drop the reference with put_device() after use.
 *
419 420
 * @fn is allowed to do anything including calling back into class
 * code.  There's no locking restriction.
421
 */
422
struct device *class_find_device(struct class *class, struct device *start,
423 424
				 const void *data,
				 int (*match)(struct device *, const void *))
425
{
426
	struct class_dev_iter iter;
427 428 429 430
	struct device *dev;

	if (!class)
		return NULL;
431 432 433 434 435
	if (!class->p) {
		WARN(1, "%s called for class '%s' before it was initialized",
		     __func__, class->name);
		return NULL;
	}
436

437 438
	class_dev_iter_init(&iter, class, start, NULL);
	while ((dev = class_dev_iter_next(&iter))) {
439
		if (match(dev, data)) {
440
			get_device(dev);
441
			break;
442
		}
443
	}
444
	class_dev_iter_exit(&iter);
445

446
	return dev;
447 448 449
}
EXPORT_SYMBOL_GPL(class_find_device);

L
Linus Torvalds 已提交
450 451 452
int class_interface_register(struct class_interface *class_intf)
{
	struct class *parent;
453
	struct class_dev_iter iter;
454
	struct device *dev;
L
Linus Torvalds 已提交
455 456 457 458 459 460 461 462

	if (!class_intf || !class_intf->class)
		return -ENODEV;

	parent = class_get(class_intf->class);
	if (!parent)
		return -EINVAL;

463 464
	mutex_lock(&parent->p->mutex);
	list_add_tail(&class_intf->node, &parent->p->interfaces);
465
	if (class_intf->add_dev) {
466 467
		class_dev_iter_init(&iter, parent, NULL, NULL);
		while ((dev = class_dev_iter_next(&iter)))
468
			class_intf->add_dev(dev, class_intf);
469
		class_dev_iter_exit(&iter);
470
	}
471
	mutex_unlock(&parent->p->mutex);
L
Linus Torvalds 已提交
472 473 474 475 476 477

	return 0;
}

void class_interface_unregister(struct class_interface *class_intf)
{
478
	struct class *parent = class_intf->class;
479
	struct class_dev_iter iter;
480
	struct device *dev;
L
Linus Torvalds 已提交
481 482 483 484

	if (!parent)
		return;

485
	mutex_lock(&parent->p->mutex);
L
Linus Torvalds 已提交
486
	list_del_init(&class_intf->node);
487
	if (class_intf->remove_dev) {
488 489
		class_dev_iter_init(&iter, parent, NULL, NULL);
		while ((dev = class_dev_iter_next(&iter)))
490
			class_intf->remove_dev(dev, class_intf);
491
		class_dev_iter_exit(&iter);
492
	}
493
	mutex_unlock(&parent->p->mutex);
L
Linus Torvalds 已提交
494 495 496 497

	class_put(parent);
}

498 499
ssize_t show_class_attr_string(struct class *class,
			       struct class_attribute *attr, char *buf)
500 501 502 503 504 505 506 507
{
	struct class_attribute_string *cs;
	cs = container_of(attr, struct class_attribute_string, attr);
	return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
}

EXPORT_SYMBOL_GPL(show_class_attr_string);

508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
struct class_compat {
	struct kobject *kobj;
};

/**
 * class_compat_register - register a compatibility class
 * @name: the name of the class
 *
 * Compatibility class are meant as a temporary user-space compatibility
 * workaround when converting a family of class devices to a bus devices.
 */
struct class_compat *class_compat_register(const char *name)
{
	struct class_compat *cls;

	cls = kmalloc(sizeof(struct class_compat), GFP_KERNEL);
	if (!cls)
		return NULL;
	cls->kobj = kobject_create_and_add(name, &class_kset->kobj);
	if (!cls->kobj) {
		kfree(cls);
		return NULL;
	}
	return cls;
}
EXPORT_SYMBOL_GPL(class_compat_register);

/**
 * class_compat_unregister - unregister a compatibility class
 * @cls: the class to unregister
 */
void class_compat_unregister(struct class_compat *cls)
{
	kobject_put(cls->kobj);
	kfree(cls);
}
EXPORT_SYMBOL_GPL(class_compat_unregister);

/**
 * class_compat_create_link - create a compatibility class device link to
 *			      a bus device
 * @cls: the compatibility class
 * @dev: the target bus device
 * @device_link: an optional device to which a "device" link should be created
 */
int class_compat_create_link(struct class_compat *cls, struct device *dev,
			     struct device *device_link)
{
	int error;

	error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev));
	if (error)
		return error;

	/*
	 * Optionally add a "device" link (typically to the parent), as a
	 * class device would have one and we want to provide as much
	 * backwards compatibility as possible.
	 */
	if (device_link) {
		error = sysfs_create_link(&dev->kobj, &device_link->kobj,
					  "device");
		if (error)
			sysfs_remove_link(cls->kobj, dev_name(dev));
	}

	return error;
}
EXPORT_SYMBOL_GPL(class_compat_create_link);

/**
 * class_compat_remove_link - remove a compatibility class device link to
 *			      a bus device
 * @cls: the compatibility class
 * @dev: the target bus device
 * @device_link: an optional device to which a "device" link was previously
 * 		 created
 */
void class_compat_remove_link(struct class_compat *cls, struct device *dev,
			      struct device *device_link)
{
	if (device_link)
		sysfs_remove_link(&dev->kobj, "device");
	sysfs_remove_link(cls->kobj, dev_name(dev));
}
EXPORT_SYMBOL_GPL(class_compat_remove_link);

L
Linus Torvalds 已提交
595 596
int __init classes_init(void)
{
597 598 599
	class_kset = kset_create_and_add("class", NULL, NULL);
	if (!class_kset)
		return -ENOMEM;
L
Linus Torvalds 已提交
600 601 602 603 604 605
	return 0;
}

EXPORT_SYMBOL_GPL(class_create_file);
EXPORT_SYMBOL_GPL(class_remove_file);
EXPORT_SYMBOL_GPL(class_unregister);
606
EXPORT_SYMBOL_GPL(class_destroy);
L
Linus Torvalds 已提交
607 608 609

EXPORT_SYMBOL_GPL(class_interface_register);
EXPORT_SYMBOL_GPL(class_interface_unregister);