1 /* 2 * class.c - basic device class management 3 * 4 * Copyright (c) 2002-3 Patrick Mochel 5 * Copyright (c) 2002-3 Open Source Development Labs 6 * Copyright (c) 2003-2004 Greg Kroah-Hartman 7 * Copyright (c) 2003-2004 IBM Corp. 8 * 9 * This file is released under the GPLv2 10 * 11 */ 12 13 #include <linux/config.h> 14 #include <linux/device.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/string.h> 18 #include <linux/kdev_t.h> 19 #include "base.h" 20 21 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 22 #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) 23 24 static ssize_t 25 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 26 { 27 struct class_attribute * class_attr = to_class_attr(attr); 28 struct class * dc = to_class(kobj); 29 ssize_t ret = 0; 30 31 if (class_attr->show) 32 ret = class_attr->show(dc, buf); 33 return ret; 34 } 35 36 static ssize_t 37 class_attr_store(struct kobject * kobj, struct attribute * attr, 38 const char * buf, size_t count) 39 { 40 struct class_attribute * class_attr = to_class_attr(attr); 41 struct class * dc = to_class(kobj); 42 ssize_t ret = 0; 43 44 if (class_attr->store) 45 ret = class_attr->store(dc, buf, count); 46 return ret; 47 } 48 49 static void class_release(struct kobject * kobj) 50 { 51 struct class *class = to_class(kobj); 52 53 pr_debug("class '%s': release.\n", class->name); 54 55 if (class->class_release) 56 class->class_release(class); 57 else 58 pr_debug("class '%s' does not have a release() function, " 59 "be careful\n", class->name); 60 } 61 62 static struct sysfs_ops class_sysfs_ops = { 63 .show = class_attr_show, 64 .store = class_attr_store, 65 }; 66 67 static struct kobj_type ktype_class = { 68 .sysfs_ops = &class_sysfs_ops, 69 .release = class_release, 70 }; 71 72 /* Hotplug events for classes go to the class_obj subsys */ 73 static decl_subsys(class, &ktype_class, NULL); 74 75 76 int class_create_file(struct class * cls, const struct class_attribute * attr) 77 { 78 int error; 79 if (cls) { 80 error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr); 81 } else 82 error = -EINVAL; 83 return error; 84 } 85 86 void class_remove_file(struct class * cls, const struct class_attribute * attr) 87 { 88 if (cls) 89 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); 90 } 91 92 struct class * class_get(struct class * cls) 93 { 94 if (cls) 95 return container_of(subsys_get(&cls->subsys), struct class, subsys); 96 return NULL; 97 } 98 99 void class_put(struct class * cls) 100 { 101 subsys_put(&cls->subsys); 102 } 103 104 105 static int add_class_attrs(struct class * cls) 106 { 107 int i; 108 int error = 0; 109 110 if (cls->class_attrs) { 111 for (i = 0; attr_name(cls->class_attrs[i]); i++) { 112 error = class_create_file(cls,&cls->class_attrs[i]); 113 if (error) 114 goto Err; 115 } 116 } 117 Done: 118 return error; 119 Err: 120 while (--i >= 0) 121 class_remove_file(cls,&cls->class_attrs[i]); 122 goto Done; 123 } 124 125 static void remove_class_attrs(struct class * cls) 126 { 127 int i; 128 129 if (cls->class_attrs) { 130 for (i = 0; attr_name(cls->class_attrs[i]); i++) 131 class_remove_file(cls,&cls->class_attrs[i]); 132 } 133 } 134 135 int class_register(struct class * cls) 136 { 137 int error; 138 139 pr_debug("device class '%s': registering\n", cls->name); 140 141 INIT_LIST_HEAD(&cls->children); 142 INIT_LIST_HEAD(&cls->interfaces); 143 init_MUTEX(&cls->sem); 144 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); 145 if (error) 146 return error; 147 148 subsys_set_kset(cls, class_subsys); 149 150 error = subsystem_register(&cls->subsys); 151 if (!error) { 152 error = add_class_attrs(class_get(cls)); 153 class_put(cls); 154 } 155 return error; 156 } 157 158 void class_unregister(struct class * cls) 159 { 160 pr_debug("device class '%s': unregistering\n", cls->name); 161 remove_class_attrs(cls); 162 subsystem_unregister(&cls->subsys); 163 } 164 165 166 /* Class Device Stuff */ 167 168 int class_device_create_file(struct class_device * class_dev, 169 const struct class_device_attribute * attr) 170 { 171 int error = -EINVAL; 172 if (class_dev) 173 error = sysfs_create_file(&class_dev->kobj, &attr->attr); 174 return error; 175 } 176 177 void class_device_remove_file(struct class_device * class_dev, 178 const struct class_device_attribute * attr) 179 { 180 if (class_dev) 181 sysfs_remove_file(&class_dev->kobj, &attr->attr); 182 } 183 184 int class_device_create_bin_file(struct class_device *class_dev, 185 struct bin_attribute *attr) 186 { 187 int error = -EINVAL; 188 if (class_dev) 189 error = sysfs_create_bin_file(&class_dev->kobj, attr); 190 return error; 191 } 192 193 void class_device_remove_bin_file(struct class_device *class_dev, 194 struct bin_attribute *attr) 195 { 196 if (class_dev) 197 sysfs_remove_bin_file(&class_dev->kobj, attr); 198 } 199 200 static ssize_t 201 class_device_attr_show(struct kobject * kobj, struct attribute * attr, 202 char * buf) 203 { 204 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 205 struct class_device * cd = to_class_dev(kobj); 206 ssize_t ret = 0; 207 208 if (class_dev_attr->show) 209 ret = class_dev_attr->show(cd, buf); 210 return ret; 211 } 212 213 static ssize_t 214 class_device_attr_store(struct kobject * kobj, struct attribute * attr, 215 const char * buf, size_t count) 216 { 217 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 218 struct class_device * cd = to_class_dev(kobj); 219 ssize_t ret = 0; 220 221 if (class_dev_attr->store) 222 ret = class_dev_attr->store(cd, buf, count); 223 return ret; 224 } 225 226 static struct sysfs_ops class_dev_sysfs_ops = { 227 .show = class_device_attr_show, 228 .store = class_device_attr_store, 229 }; 230 231 static void class_dev_release(struct kobject * kobj) 232 { 233 struct class_device *cd = to_class_dev(kobj); 234 struct class * cls = cd->class; 235 236 pr_debug("device class '%s': release.\n", cd->class_id); 237 238 if (cls->release) 239 cls->release(cd); 240 else { 241 printk(KERN_ERR "Device class '%s' does not have a release() function, " 242 "it is broken and must be fixed.\n", 243 cd->class_id); 244 WARN_ON(1); 245 } 246 } 247 248 static struct kobj_type ktype_class_device = { 249 .sysfs_ops = &class_dev_sysfs_ops, 250 .release = class_dev_release, 251 }; 252 253 static int class_hotplug_filter(struct kset *kset, struct kobject *kobj) 254 { 255 struct kobj_type *ktype = get_ktype(kobj); 256 257 if (ktype == &ktype_class_device) { 258 struct class_device *class_dev = to_class_dev(kobj); 259 if (class_dev->class) 260 return 1; 261 } 262 return 0; 263 } 264 265 static char *class_hotplug_name(struct kset *kset, struct kobject *kobj) 266 { 267 struct class_device *class_dev = to_class_dev(kobj); 268 269 return class_dev->class->name; 270 } 271 272 static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp, 273 int num_envp, char *buffer, int buffer_size) 274 { 275 struct class_device *class_dev = to_class_dev(kobj); 276 int i = 0; 277 int length = 0; 278 int retval = 0; 279 280 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); 281 282 if (class_dev->dev) { 283 /* add physical device, backing this device */ 284 struct device *dev = class_dev->dev; 285 char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); 286 287 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, 288 &length, "PHYSDEVPATH=%s", path); 289 kfree(path); 290 291 if (dev->bus) 292 add_hotplug_env_var(envp, num_envp, &i, 293 buffer, buffer_size, &length, 294 "PHYSDEVBUS=%s", dev->bus->name); 295 296 if (dev->driver) 297 add_hotplug_env_var(envp, num_envp, &i, 298 buffer, buffer_size, &length, 299 "PHYSDEVDRIVER=%s", dev->driver->name); 300 } 301 302 if (MAJOR(class_dev->devt)) { 303 add_hotplug_env_var(envp, num_envp, &i, 304 buffer, buffer_size, &length, 305 "MAJOR=%u", MAJOR(class_dev->devt)); 306 307 add_hotplug_env_var(envp, num_envp, &i, 308 buffer, buffer_size, &length, 309 "MINOR=%u", MINOR(class_dev->devt)); 310 } 311 312 /* terminate, set to next free slot, shrink available space */ 313 envp[i] = NULL; 314 envp = &envp[i]; 315 num_envp -= i; 316 buffer = &buffer[length]; 317 buffer_size -= length; 318 319 if (class_dev->class->hotplug) { 320 /* have the bus specific function add its stuff */ 321 retval = class_dev->class->hotplug (class_dev, envp, num_envp, 322 buffer, buffer_size); 323 if (retval) { 324 pr_debug ("%s - hotplug() returned %d\n", 325 __FUNCTION__, retval); 326 } 327 } 328 329 return retval; 330 } 331 332 static struct kset_hotplug_ops class_hotplug_ops = { 333 .filter = class_hotplug_filter, 334 .name = class_hotplug_name, 335 .hotplug = class_hotplug, 336 }; 337 338 static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops); 339 340 341 static int class_device_add_attrs(struct class_device * cd) 342 { 343 int i; 344 int error = 0; 345 struct class * cls = cd->class; 346 347 if (cls->class_dev_attrs) { 348 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { 349 error = class_device_create_file(cd, 350 &cls->class_dev_attrs[i]); 351 if (error) 352 goto Err; 353 } 354 } 355 Done: 356 return error; 357 Err: 358 while (--i >= 0) 359 class_device_remove_file(cd,&cls->class_dev_attrs[i]); 360 goto Done; 361 } 362 363 static void class_device_remove_attrs(struct class_device * cd) 364 { 365 int i; 366 struct class * cls = cd->class; 367 368 if (cls->class_dev_attrs) { 369 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) 370 class_device_remove_file(cd,&cls->class_dev_attrs[i]); 371 } 372 } 373 374 static ssize_t show_dev(struct class_device *class_dev, char *buf) 375 { 376 return print_dev_t(buf, class_dev->devt); 377 } 378 static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); 379 380 void class_device_initialize(struct class_device *class_dev) 381 { 382 kobj_set_kset_s(class_dev, class_obj_subsys); 383 kobject_init(&class_dev->kobj); 384 INIT_LIST_HEAD(&class_dev->node); 385 } 386 387 int class_device_add(struct class_device *class_dev) 388 { 389 struct class * parent = NULL; 390 struct class_interface * class_intf; 391 int error; 392 393 class_dev = class_device_get(class_dev); 394 if (!class_dev) 395 return -EINVAL; 396 397 if (!strlen(class_dev->class_id)) { 398 error = -EINVAL; 399 goto register_done; 400 } 401 402 parent = class_get(class_dev->class); 403 404 pr_debug("CLASS: registering class device: ID = '%s'\n", 405 class_dev->class_id); 406 407 /* first, register with generic layer. */ 408 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 409 if (parent) 410 class_dev->kobj.parent = &parent->subsys.kset.kobj; 411 412 if ((error = kobject_add(&class_dev->kobj))) 413 goto register_done; 414 415 /* now take care of our own registration */ 416 if (parent) { 417 down(&parent->sem); 418 list_add_tail(&class_dev->node, &parent->children); 419 list_for_each_entry(class_intf, &parent->interfaces, node) 420 if (class_intf->add) 421 class_intf->add(class_dev); 422 up(&parent->sem); 423 } 424 425 if (MAJOR(class_dev->devt)) 426 class_device_create_file(class_dev, &class_device_attr_dev); 427 428 class_device_add_attrs(class_dev); 429 if (class_dev->dev) 430 sysfs_create_link(&class_dev->kobj, 431 &class_dev->dev->kobj, "device"); 432 433 register_done: 434 if (error && parent) 435 class_put(parent); 436 class_device_put(class_dev); 437 return error; 438 } 439 440 int class_device_register(struct class_device *class_dev) 441 { 442 class_device_initialize(class_dev); 443 return class_device_add(class_dev); 444 } 445 446 void class_device_del(struct class_device *class_dev) 447 { 448 struct class * parent = class_dev->class; 449 struct class_interface * class_intf; 450 451 if (parent) { 452 down(&parent->sem); 453 list_del_init(&class_dev->node); 454 list_for_each_entry(class_intf, &parent->interfaces, node) 455 if (class_intf->remove) 456 class_intf->remove(class_dev); 457 up(&parent->sem); 458 } 459 460 if (class_dev->dev) 461 sysfs_remove_link(&class_dev->kobj, "device"); 462 class_device_remove_attrs(class_dev); 463 464 kobject_del(&class_dev->kobj); 465 466 if (parent) 467 class_put(parent); 468 } 469 470 void class_device_unregister(struct class_device *class_dev) 471 { 472 pr_debug("CLASS: Unregistering class device. ID = '%s'\n", 473 class_dev->class_id); 474 class_device_del(class_dev); 475 class_device_put(class_dev); 476 } 477 478 int class_device_rename(struct class_device *class_dev, char *new_name) 479 { 480 int error = 0; 481 482 class_dev = class_device_get(class_dev); 483 if (!class_dev) 484 return -EINVAL; 485 486 pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, 487 new_name); 488 489 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); 490 491 error = kobject_rename(&class_dev->kobj, new_name); 492 493 class_device_put(class_dev); 494 495 return error; 496 } 497 498 struct class_device * class_device_get(struct class_device *class_dev) 499 { 500 if (class_dev) 501 return to_class_dev(kobject_get(&class_dev->kobj)); 502 return NULL; 503 } 504 505 void class_device_put(struct class_device *class_dev) 506 { 507 kobject_put(&class_dev->kobj); 508 } 509 510 511 int class_interface_register(struct class_interface *class_intf) 512 { 513 struct class *parent; 514 struct class_device *class_dev; 515 516 if (!class_intf || !class_intf->class) 517 return -ENODEV; 518 519 parent = class_get(class_intf->class); 520 if (!parent) 521 return -EINVAL; 522 523 down(&parent->sem); 524 list_add_tail(&class_intf->node, &parent->interfaces); 525 if (class_intf->add) { 526 list_for_each_entry(class_dev, &parent->children, node) 527 class_intf->add(class_dev); 528 } 529 up(&parent->sem); 530 531 return 0; 532 } 533 534 void class_interface_unregister(struct class_interface *class_intf) 535 { 536 struct class * parent = class_intf->class; 537 struct class_device *class_dev; 538 539 if (!parent) 540 return; 541 542 down(&parent->sem); 543 list_del_init(&class_intf->node); 544 if (class_intf->remove) { 545 list_for_each_entry(class_dev, &parent->children, node) 546 class_intf->remove(class_dev); 547 } 548 up(&parent->sem); 549 550 class_put(parent); 551 } 552 553 554 555 int __init classes_init(void) 556 { 557 int retval; 558 559 retval = subsystem_register(&class_subsys); 560 if (retval) 561 return retval; 562 563 /* ick, this is ugly, the things we go through to keep from showing up 564 * in sysfs... */ 565 subsystem_init(&class_obj_subsys); 566 if (!class_obj_subsys.kset.subsys) 567 class_obj_subsys.kset.subsys = &class_obj_subsys; 568 return 0; 569 } 570 571 EXPORT_SYMBOL_GPL(class_create_file); 572 EXPORT_SYMBOL_GPL(class_remove_file); 573 EXPORT_SYMBOL_GPL(class_register); 574 EXPORT_SYMBOL_GPL(class_unregister); 575 EXPORT_SYMBOL_GPL(class_get); 576 EXPORT_SYMBOL_GPL(class_put); 577 578 EXPORT_SYMBOL_GPL(class_device_register); 579 EXPORT_SYMBOL_GPL(class_device_unregister); 580 EXPORT_SYMBOL_GPL(class_device_initialize); 581 EXPORT_SYMBOL_GPL(class_device_add); 582 EXPORT_SYMBOL_GPL(class_device_del); 583 EXPORT_SYMBOL_GPL(class_device_get); 584 EXPORT_SYMBOL_GPL(class_device_put); 585 EXPORT_SYMBOL_GPL(class_device_create_file); 586 EXPORT_SYMBOL_GPL(class_device_remove_file); 587 EXPORT_SYMBOL_GPL(class_device_create_bin_file); 588 EXPORT_SYMBOL_GPL(class_device_remove_bin_file); 589 590 EXPORT_SYMBOL_GPL(class_interface_register); 591 EXPORT_SYMBOL_GPL(class_interface_unregister); 592