class.c 14 KB

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