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