1/* 2 * attribute_container.c - implementation of a simple container for classes 3 * 4 * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com> 5 * 6 * This file is licensed under GPLv2 7 * 8 * The basic idea here is to enable a device to be attached to an 9 * aritrary numer of classes without having to allocate storage for them. 10 * Instead, the contained classes select the devices they need to attach 11 * to via a matching function. 12 */ 13 14#include <linux/attribute_container.h> 15#include <linux/init.h> 16#include <linux/device.h> 17#include <linux/kernel.h> 18#include <linux/slab.h> 19#include <linux/list.h> 20#include <linux/module.h> 21#include <linux/mutex.h> 22 23#include "base.h" 24 25/* This is a private structure used to tie the classdev and the 26 * container .. it should never be visible outside this file */ 27struct internal_container { 28 struct klist_node node; 29 struct attribute_container *cont; 30 struct device classdev; 31}; 32 33static void internal_container_klist_get(struct klist_node *n) 34{ 35 struct internal_container *ic = 36 container_of(n, struct internal_container, node); 37 get_device(&ic->classdev); 38} 39 40static void internal_container_klist_put(struct klist_node *n) 41{ 42 struct internal_container *ic = 43 container_of(n, struct internal_container, node); 44 put_device(&ic->classdev); 45} 46 47 48/** 49 * attribute_container_classdev_to_container - given a classdev, return the container 50 * 51 * @classdev: the class device created by attribute_container_add_device. 52 * 53 * Returns the container associated with this classdev. 54 */ 55struct attribute_container * 56attribute_container_classdev_to_container(struct device *classdev) 57{ 58 struct internal_container *ic = 59 container_of(classdev, struct internal_container, classdev); 60 return ic->cont; 61} 62EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); 63 64static LIST_HEAD(attribute_container_list); 65 66static DEFINE_MUTEX(attribute_container_mutex); 67 68/** 69 * attribute_container_register - register an attribute container 70 * 71 * @cont: The container to register. This must be allocated by the 72 * callee and should also be zeroed by it. 73 */ 74int 75attribute_container_register(struct attribute_container *cont) 76{ 77 INIT_LIST_HEAD(&cont->node); 78 klist_init(&cont->containers,internal_container_klist_get, 79 internal_container_klist_put); 80 81 mutex_lock(&attribute_container_mutex); 82 list_add_tail(&cont->node, &attribute_container_list); 83 mutex_unlock(&attribute_container_mutex); 84 85 return 0; 86} 87EXPORT_SYMBOL_GPL(attribute_container_register); 88 89/** 90 * attribute_container_unregister - remove a container registration 91 * 92 * @cont: previously registered container to remove 93 */ 94int 95attribute_container_unregister(struct attribute_container *cont) 96{ 97 int retval = -EBUSY; 98 mutex_lock(&attribute_container_mutex); 99 spin_lock(&cont->containers.k_lock); 100 if (!list_empty(&cont->containers.k_list)) 101 goto out; 102 retval = 0; 103 list_del(&cont->node); 104 out: 105 spin_unlock(&cont->containers.k_lock); 106 mutex_unlock(&attribute_container_mutex); 107 return retval; 108 109} 110EXPORT_SYMBOL_GPL(attribute_container_unregister); 111 112/* private function used as class release */ 113static void attribute_container_release(struct device *classdev) 114{ 115 struct internal_container *ic 116 = container_of(classdev, struct internal_container, classdev); 117 struct device *dev = classdev->parent; 118 119 kfree(ic); 120 put_device(dev); 121} 122 123/** 124 * attribute_container_add_device - see if any container is interested in dev 125 * 126 * @dev: device to add attributes to 127 * @fn: function to trigger addition of class device. 128 * 129 * This function allocates storage for the class device(s) to be 130 * attached to dev (one for each matching attribute_container). If no 131 * fn is provided, the code will simply register the class device via 132 * device_add. If a function is provided, it is expected to add 133 * the class device at the appropriate time. One of the things that 134 * might be necessary is to allocate and initialise the classdev and 135 * then add it a later time. To do this, call this routine for 136 * allocation and initialisation and then use 137 * attribute_container_device_trigger() to call device_add() on 138 * it. Note: after this, the class device contains a reference to dev 139 * which is not relinquished until the release of the classdev. 140 */ 141void 142attribute_container_add_device(struct device *dev, 143 int (*fn)(struct attribute_container *, 144 struct device *, 145 struct device *)) 146{ 147 struct attribute_container *cont; 148 149 mutex_lock(&attribute_container_mutex); 150 list_for_each_entry(cont, &attribute_container_list, node) { 151 struct internal_container *ic; 152 153 if (attribute_container_no_classdevs(cont)) 154 continue; 155 156 if (!cont->match(cont, dev)) 157 continue; 158 159 ic = kzalloc(sizeof(*ic), GFP_KERNEL); 160 if (!ic) { 161 dev_printk(KERN_ERR, dev, "failed to allocate class container\n"); 162 continue; 163 } 164 165 ic->cont = cont; 166 device_initialize(&ic->classdev); 167 ic->classdev.parent = get_device(dev); 168 ic->classdev.class = cont->class; 169 cont->class->dev_release = attribute_container_release; 170 dev_set_name(&ic->classdev, dev_name(dev)); 171 if (fn) 172 fn(cont, dev, &ic->classdev); 173 else 174 attribute_container_add_class_device(&ic->classdev); 175 klist_add_tail(&ic->node, &cont->containers); 176 } 177 mutex_unlock(&attribute_container_mutex); 178} 179 180#define klist_for_each_entry(pos, head, member, iter) \ 181 for (klist_iter_init(head, iter); (pos = ({ \ 182 struct klist_node *n = klist_next(iter); \ 183 n ? container_of(n, typeof(*pos), member) : \ 184 ({ klist_iter_exit(iter) ; NULL; }); \ 185 }) ) != NULL; ) 186 187 188/** 189 * attribute_container_remove_device - make device eligible for removal. 190 * 191 * @dev: The generic device 192 * @fn: A function to call to remove the device 193 * 194 * This routine triggers device removal. If fn is NULL, then it is 195 * simply done via device_unregister (note that if something 196 * still has a reference to the classdev, then the memory occupied 197 * will not be freed until the classdev is released). If you want a 198 * two phase release: remove from visibility and then delete the 199 * device, then you should use this routine with a fn that calls 200 * device_del() and then use attribute_container_device_trigger() 201 * to do the final put on the classdev. 202 */ 203void 204attribute_container_remove_device(struct device *dev, 205 void (*fn)(struct attribute_container *, 206 struct device *, 207 struct device *)) 208{ 209 struct attribute_container *cont; 210 211 mutex_lock(&attribute_container_mutex); 212 list_for_each_entry(cont, &attribute_container_list, node) { 213 struct internal_container *ic; 214 struct klist_iter iter; 215 216 if (attribute_container_no_classdevs(cont)) 217 continue; 218 219 if (!cont->match(cont, dev)) 220 continue; 221 222 klist_for_each_entry(ic, &cont->containers, node, &iter) { 223 if (dev != ic->classdev.parent) 224 continue; 225 klist_del(&ic->node); 226 if (fn) 227 fn(cont, dev, &ic->classdev); 228 else { 229 attribute_container_remove_attrs(&ic->classdev); 230 device_unregister(&ic->classdev); 231 } 232 } 233 } 234 mutex_unlock(&attribute_container_mutex); 235} 236 237/** 238 * attribute_container_device_trigger - execute a trigger for each matching classdev 239 * 240 * @dev: The generic device to run the trigger for 241 * @fn the function to execute for each classdev. 242 * 243 * This funcion is for executing a trigger when you need to know both 244 * the container and the classdev. If you only care about the 245 * container, then use attribute_container_trigger() instead. 246 */ 247void 248attribute_container_device_trigger(struct device *dev, 249 int (*fn)(struct attribute_container *, 250 struct device *, 251 struct device *)) 252{ 253 struct attribute_container *cont; 254 255 mutex_lock(&attribute_container_mutex); 256 list_for_each_entry(cont, &attribute_container_list, node) { 257 struct internal_container *ic; 258 struct klist_iter iter; 259 260 if (!cont->match(cont, dev)) 261 continue; 262 263 if (attribute_container_no_classdevs(cont)) { 264 fn(cont, dev, NULL); 265 continue; 266 } 267 268 klist_for_each_entry(ic, &cont->containers, node, &iter) { 269 if (dev == ic->classdev.parent) 270 fn(cont, dev, &ic->classdev); 271 } 272 } 273 mutex_unlock(&attribute_container_mutex); 274} 275 276/** 277 * attribute_container_trigger - trigger a function for each matching container 278 * 279 * @dev: The generic device to activate the trigger for 280 * @fn: the function to trigger 281 * 282 * This routine triggers a function that only needs to know the 283 * matching containers (not the classdev) associated with a device. 284 * It is more lightweight than attribute_container_device_trigger, so 285 * should be used in preference unless the triggering function 286 * actually needs to know the classdev. 287 */ 288void 289attribute_container_trigger(struct device *dev, 290 int (*fn)(struct attribute_container *, 291 struct device *)) 292{ 293 struct attribute_container *cont; 294 295 mutex_lock(&attribute_container_mutex); 296 list_for_each_entry(cont, &attribute_container_list, node) { 297 if (cont->match(cont, dev)) 298 fn(cont, dev); 299 } 300 mutex_unlock(&attribute_container_mutex); 301} 302 303/** 304 * attribute_container_add_attrs - add attributes 305 * 306 * @classdev: The class device 307 * 308 * This simply creates all the class device sysfs files from the 309 * attributes listed in the container 310 */ 311int 312attribute_container_add_attrs(struct device *classdev) 313{ 314 struct attribute_container *cont = 315 attribute_container_classdev_to_container(classdev); 316 struct device_attribute **attrs = cont->attrs; 317 int i, error; 318 319 BUG_ON(attrs && cont->grp); 320 321 if (!attrs && !cont->grp) 322 return 0; 323 324 if (cont->grp) 325 return sysfs_create_group(&classdev->kobj, cont->grp); 326 327 for (i = 0; attrs[i]; i++) { 328 sysfs_attr_init(&attrs[i]->attr); 329 error = device_create_file(classdev, attrs[i]); 330 if (error) 331 return error; 332 } 333 334 return 0; 335} 336 337/** 338 * attribute_container_add_class_device - same function as device_add 339 * 340 * @classdev: the class device to add 341 * 342 * This performs essentially the same function as device_add except for 343 * attribute containers, namely add the classdev to the system and then 344 * create the attribute files 345 */ 346int 347attribute_container_add_class_device(struct device *classdev) 348{ 349 int error = device_add(classdev); 350 if (error) 351 return error; 352 return attribute_container_add_attrs(classdev); 353} 354 355/** 356 * attribute_container_add_class_device_adapter - simple adapter for triggers 357 * 358 * This function is identical to attribute_container_add_class_device except 359 * that it is designed to be called from the triggers 360 */ 361int 362attribute_container_add_class_device_adapter(struct attribute_container *cont, 363 struct device *dev, 364 struct device *classdev) 365{ 366 return attribute_container_add_class_device(classdev); 367} 368 369/** 370 * attribute_container_remove_attrs - remove any attribute files 371 * 372 * @classdev: The class device to remove the files from 373 * 374 */ 375void 376attribute_container_remove_attrs(struct device *classdev) 377{ 378 struct attribute_container *cont = 379 attribute_container_classdev_to_container(classdev); 380 struct device_attribute **attrs = cont->attrs; 381 int i; 382 383 if (!attrs && !cont->grp) 384 return; 385 386 if (cont->grp) { 387 sysfs_remove_group(&classdev->kobj, cont->grp); 388 return ; 389 } 390 391 for (i = 0; attrs[i]; i++) 392 device_remove_file(classdev, attrs[i]); 393} 394 395/** 396 * attribute_container_class_device_del - equivalent of class_device_del 397 * 398 * @classdev: the class device 399 * 400 * This function simply removes all the attribute files and then calls 401 * device_del. 402 */ 403void 404attribute_container_class_device_del(struct device *classdev) 405{ 406 attribute_container_remove_attrs(classdev); 407 device_del(classdev); 408} 409 410/** 411 * attribute_container_find_class_device - find the corresponding class_device 412 * 413 * @cont: the container 414 * @dev: the generic device 415 * 416 * Looks up the device in the container's list of class devices and returns 417 * the corresponding class_device. 418 */ 419struct device * 420attribute_container_find_class_device(struct attribute_container *cont, 421 struct device *dev) 422{ 423 struct device *cdev = NULL; 424 struct internal_container *ic; 425 struct klist_iter iter; 426 427 klist_for_each_entry(ic, &cont->containers, node, &iter) { 428 if (ic->classdev.parent == dev) { 429 cdev = &ic->classdev; 430 klist_iter_exit(&iter); 431 break; 432 } 433 } 434 435 return cdev; 436} 437EXPORT_SYMBOL_GPL(attribute_container_find_class_device); 438