Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * attribute_container.c - implementation of a simple container for classes
0004  *
0005  * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
0006  *
0007  * The basic idea here is to enable a device to be attached to an
0008  * aritrary numer of classes without having to allocate storage for them.
0009  * Instead, the contained classes select the devices they need to attach
0010  * to via a matching function.
0011  */
0012 
0013 #include <linux/attribute_container.h>
0014 #include <linux/device.h>
0015 #include <linux/kernel.h>
0016 #include <linux/slab.h>
0017 #include <linux/list.h>
0018 #include <linux/module.h>
0019 #include <linux/mutex.h>
0020 
0021 #include "base.h"
0022 
0023 /* This is a private structure used to tie the classdev and the
0024  * container .. it should never be visible outside this file */
0025 struct internal_container {
0026     struct klist_node node;
0027     struct attribute_container *cont;
0028     struct device classdev;
0029 };
0030 
0031 static void internal_container_klist_get(struct klist_node *n)
0032 {
0033     struct internal_container *ic =
0034         container_of(n, struct internal_container, node);
0035     get_device(&ic->classdev);
0036 }
0037 
0038 static void internal_container_klist_put(struct klist_node *n)
0039 {
0040     struct internal_container *ic =
0041         container_of(n, struct internal_container, node);
0042     put_device(&ic->classdev);
0043 }
0044 
0045 
0046 /**
0047  * attribute_container_classdev_to_container - given a classdev, return the container
0048  *
0049  * @classdev: the class device created by attribute_container_add_device.
0050  *
0051  * Returns the container associated with this classdev.
0052  */
0053 struct attribute_container *
0054 attribute_container_classdev_to_container(struct device *classdev)
0055 {
0056     struct internal_container *ic =
0057         container_of(classdev, struct internal_container, classdev);
0058     return ic->cont;
0059 }
0060 EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container);
0061 
0062 static LIST_HEAD(attribute_container_list);
0063 
0064 static DEFINE_MUTEX(attribute_container_mutex);
0065 
0066 /**
0067  * attribute_container_register - register an attribute container
0068  *
0069  * @cont: The container to register.  This must be allocated by the
0070  *        callee and should also be zeroed by it.
0071  */
0072 int
0073 attribute_container_register(struct attribute_container *cont)
0074 {
0075     INIT_LIST_HEAD(&cont->node);
0076     klist_init(&cont->containers, internal_container_klist_get,
0077            internal_container_klist_put);
0078 
0079     mutex_lock(&attribute_container_mutex);
0080     list_add_tail(&cont->node, &attribute_container_list);
0081     mutex_unlock(&attribute_container_mutex);
0082 
0083     return 0;
0084 }
0085 EXPORT_SYMBOL_GPL(attribute_container_register);
0086 
0087 /**
0088  * attribute_container_unregister - remove a container registration
0089  *
0090  * @cont: previously registered container to remove
0091  */
0092 int
0093 attribute_container_unregister(struct attribute_container *cont)
0094 {
0095     int retval = -EBUSY;
0096 
0097     mutex_lock(&attribute_container_mutex);
0098     spin_lock(&cont->containers.k_lock);
0099     if (!list_empty(&cont->containers.k_list))
0100         goto out;
0101     retval = 0;
0102     list_del(&cont->node);
0103  out:
0104     spin_unlock(&cont->containers.k_lock);
0105     mutex_unlock(&attribute_container_mutex);
0106     return retval;
0107 
0108 }
0109 EXPORT_SYMBOL_GPL(attribute_container_unregister);
0110 
0111 /* private function used as class release */
0112 static void attribute_container_release(struct device *classdev)
0113 {
0114     struct internal_container *ic
0115         = container_of(classdev, struct internal_container, classdev);
0116     struct device *dev = classdev->parent;
0117 
0118     kfree(ic);
0119     put_device(dev);
0120 }
0121 
0122 /**
0123  * attribute_container_add_device - see if any container is interested in dev
0124  *
0125  * @dev: device to add attributes to
0126  * @fn:  function to trigger addition of class device.
0127  *
0128  * This function allocates storage for the class device(s) to be
0129  * attached to dev (one for each matching attribute_container).  If no
0130  * fn is provided, the code will simply register the class device via
0131  * device_add.  If a function is provided, it is expected to add
0132  * the class device at the appropriate time.  One of the things that
0133  * might be necessary is to allocate and initialise the classdev and
0134  * then add it a later time.  To do this, call this routine for
0135  * allocation and initialisation and then use
0136  * attribute_container_device_trigger() to call device_add() on
0137  * it.  Note: after this, the class device contains a reference to dev
0138  * which is not relinquished until the release of the classdev.
0139  */
0140 void
0141 attribute_container_add_device(struct device *dev,
0142                    int (*fn)(struct attribute_container *,
0143                      struct device *,
0144                      struct device *))
0145 {
0146     struct attribute_container *cont;
0147 
0148     mutex_lock(&attribute_container_mutex);
0149     list_for_each_entry(cont, &attribute_container_list, node) {
0150         struct internal_container *ic;
0151 
0152         if (attribute_container_no_classdevs(cont))
0153             continue;
0154 
0155         if (!cont->match(cont, dev))
0156             continue;
0157 
0158         ic = kzalloc(sizeof(*ic), GFP_KERNEL);
0159         if (!ic) {
0160             dev_err(dev, "failed to allocate class container\n");
0161             continue;
0162         }
0163 
0164         ic->cont = cont;
0165         device_initialize(&ic->classdev);
0166         ic->classdev.parent = get_device(dev);
0167         ic->classdev.class = cont->class;
0168         cont->class->dev_release = attribute_container_release;
0169         dev_set_name(&ic->classdev, "%s", dev_name(dev));
0170         if (fn)
0171             fn(cont, dev, &ic->classdev);
0172         else
0173             attribute_container_add_class_device(&ic->classdev);
0174         klist_add_tail(&ic->node, &cont->containers);
0175     }
0176     mutex_unlock(&attribute_container_mutex);
0177 }
0178 
0179 /* FIXME: can't break out of this unless klist_iter_exit is also
0180  * called before doing the break
0181  */
0182 #define klist_for_each_entry(pos, head, member, iter) \
0183     for (klist_iter_init(head, iter); (pos = ({ \
0184         struct klist_node *n = klist_next(iter); \
0185         n ? container_of(n, typeof(*pos), member) : \
0186             ({ klist_iter_exit(iter) ; NULL; }); \
0187     })) != NULL;)
0188 
0189 
0190 /**
0191  * attribute_container_remove_device - make device eligible for removal.
0192  *
0193  * @dev:  The generic device
0194  * @fn:   A function to call to remove the device
0195  *
0196  * This routine triggers device removal.  If fn is NULL, then it is
0197  * simply done via device_unregister (note that if something
0198  * still has a reference to the classdev, then the memory occupied
0199  * will not be freed until the classdev is released).  If you want a
0200  * two phase release: remove from visibility and then delete the
0201  * device, then you should use this routine with a fn that calls
0202  * device_del() and then use attribute_container_device_trigger()
0203  * to do the final put on the classdev.
0204  */
0205 void
0206 attribute_container_remove_device(struct device *dev,
0207                   void (*fn)(struct attribute_container *,
0208                          struct device *,
0209                          struct device *))
0210 {
0211     struct attribute_container *cont;
0212 
0213     mutex_lock(&attribute_container_mutex);
0214     list_for_each_entry(cont, &attribute_container_list, node) {
0215         struct internal_container *ic;
0216         struct klist_iter iter;
0217 
0218         if (attribute_container_no_classdevs(cont))
0219             continue;
0220 
0221         if (!cont->match(cont, dev))
0222             continue;
0223 
0224         klist_for_each_entry(ic, &cont->containers, node, &iter) {
0225             if (dev != ic->classdev.parent)
0226                 continue;
0227             klist_del(&ic->node);
0228             if (fn)
0229                 fn(cont, dev, &ic->classdev);
0230             else {
0231                 attribute_container_remove_attrs(&ic->classdev);
0232                 device_unregister(&ic->classdev);
0233             }
0234         }
0235     }
0236     mutex_unlock(&attribute_container_mutex);
0237 }
0238 
0239 static int
0240 do_attribute_container_device_trigger_safe(struct device *dev,
0241                        struct attribute_container *cont,
0242                        int (*fn)(struct attribute_container *,
0243                              struct device *, struct device *),
0244                        int (*undo)(struct attribute_container *,
0245                                struct device *, struct device *))
0246 {
0247     int ret;
0248     struct internal_container *ic, *failed;
0249     struct klist_iter iter;
0250 
0251     if (attribute_container_no_classdevs(cont))
0252         return fn(cont, dev, NULL);
0253 
0254     klist_for_each_entry(ic, &cont->containers, node, &iter) {
0255         if (dev == ic->classdev.parent) {
0256             ret = fn(cont, dev, &ic->classdev);
0257             if (ret) {
0258                 failed = ic;
0259                 klist_iter_exit(&iter);
0260                 goto fail;
0261             }
0262         }
0263     }
0264     return 0;
0265 
0266 fail:
0267     if (!undo)
0268         return ret;
0269 
0270     /* Attempt to undo the work partially done. */
0271     klist_for_each_entry(ic, &cont->containers, node, &iter) {
0272         if (ic == failed) {
0273             klist_iter_exit(&iter);
0274             break;
0275         }
0276         if (dev == ic->classdev.parent)
0277             undo(cont, dev, &ic->classdev);
0278     }
0279     return ret;
0280 }
0281 
0282 /**
0283  * attribute_container_device_trigger_safe - execute a trigger for each
0284  * matching classdev or fail all of them.
0285  *
0286  * @dev:  The generic device to run the trigger for
0287  * @fn:   the function to execute for each classdev.
0288  * @undo: A function to undo the work previously done in case of error
0289  *
0290  * This function is a safe version of
0291  * attribute_container_device_trigger. It stops on the first error and
0292  * undo the partial work that has been done, on previous classdev.  It
0293  * is guaranteed that either they all succeeded, or none of them
0294  * succeeded.
0295  */
0296 int
0297 attribute_container_device_trigger_safe(struct device *dev,
0298                     int (*fn)(struct attribute_container *,
0299                           struct device *,
0300                           struct device *),
0301                     int (*undo)(struct attribute_container *,
0302                             struct device *,
0303                             struct device *))
0304 {
0305     struct attribute_container *cont, *failed = NULL;
0306     int ret = 0;
0307 
0308     mutex_lock(&attribute_container_mutex);
0309 
0310     list_for_each_entry(cont, &attribute_container_list, node) {
0311 
0312         if (!cont->match(cont, dev))
0313             continue;
0314 
0315         ret = do_attribute_container_device_trigger_safe(dev, cont,
0316                                  fn, undo);
0317         if (ret) {
0318             failed = cont;
0319             break;
0320         }
0321     }
0322 
0323     if (ret && !WARN_ON(!undo)) {
0324         list_for_each_entry(cont, &attribute_container_list, node) {
0325 
0326             if (failed == cont)
0327                 break;
0328 
0329             if (!cont->match(cont, dev))
0330                 continue;
0331 
0332             do_attribute_container_device_trigger_safe(dev, cont,
0333                                    undo, NULL);
0334         }
0335     }
0336 
0337     mutex_unlock(&attribute_container_mutex);
0338     return ret;
0339 
0340 }
0341 
0342 /**
0343  * attribute_container_device_trigger - execute a trigger for each matching classdev
0344  *
0345  * @dev:  The generic device to run the trigger for
0346  * @fn:   the function to execute for each classdev.
0347  *
0348  * This function is for executing a trigger when you need to know both
0349  * the container and the classdev.  If you only care about the
0350  * container, then use attribute_container_trigger() instead.
0351  */
0352 void
0353 attribute_container_device_trigger(struct device *dev,
0354                    int (*fn)(struct attribute_container *,
0355                          struct device *,
0356                          struct device *))
0357 {
0358     struct attribute_container *cont;
0359 
0360     mutex_lock(&attribute_container_mutex);
0361     list_for_each_entry(cont, &attribute_container_list, node) {
0362         struct internal_container *ic;
0363         struct klist_iter iter;
0364 
0365         if (!cont->match(cont, dev))
0366             continue;
0367 
0368         if (attribute_container_no_classdevs(cont)) {
0369             fn(cont, dev, NULL);
0370             continue;
0371         }
0372 
0373         klist_for_each_entry(ic, &cont->containers, node, &iter) {
0374             if (dev == ic->classdev.parent)
0375                 fn(cont, dev, &ic->classdev);
0376         }
0377     }
0378     mutex_unlock(&attribute_container_mutex);
0379 }
0380 
0381 /**
0382  * attribute_container_trigger - trigger a function for each matching container
0383  *
0384  * @dev:  The generic device to activate the trigger for
0385  * @fn:   the function to trigger
0386  *
0387  * This routine triggers a function that only needs to know the
0388  * matching containers (not the classdev) associated with a device.
0389  * It is more lightweight than attribute_container_device_trigger, so
0390  * should be used in preference unless the triggering function
0391  * actually needs to know the classdev.
0392  */
0393 void
0394 attribute_container_trigger(struct device *dev,
0395                 int (*fn)(struct attribute_container *,
0396                       struct device *))
0397 {
0398     struct attribute_container *cont;
0399 
0400     mutex_lock(&attribute_container_mutex);
0401     list_for_each_entry(cont, &attribute_container_list, node) {
0402         if (cont->match(cont, dev))
0403             fn(cont, dev);
0404     }
0405     mutex_unlock(&attribute_container_mutex);
0406 }
0407 
0408 /**
0409  * attribute_container_add_attrs - add attributes
0410  *
0411  * @classdev: The class device
0412  *
0413  * This simply creates all the class device sysfs files from the
0414  * attributes listed in the container
0415  */
0416 int
0417 attribute_container_add_attrs(struct device *classdev)
0418 {
0419     struct attribute_container *cont =
0420         attribute_container_classdev_to_container(classdev);
0421     struct device_attribute **attrs = cont->attrs;
0422     int i, error;
0423 
0424     BUG_ON(attrs && cont->grp);
0425 
0426     if (!attrs && !cont->grp)
0427         return 0;
0428 
0429     if (cont->grp)
0430         return sysfs_create_group(&classdev->kobj, cont->grp);
0431 
0432     for (i = 0; attrs[i]; i++) {
0433         sysfs_attr_init(&attrs[i]->attr);
0434         error = device_create_file(classdev, attrs[i]);
0435         if (error)
0436             return error;
0437     }
0438 
0439     return 0;
0440 }
0441 
0442 /**
0443  * attribute_container_add_class_device - same function as device_add
0444  *
0445  * @classdev:   the class device to add
0446  *
0447  * This performs essentially the same function as device_add except for
0448  * attribute containers, namely add the classdev to the system and then
0449  * create the attribute files
0450  */
0451 int
0452 attribute_container_add_class_device(struct device *classdev)
0453 {
0454     int error = device_add(classdev);
0455 
0456     if (error)
0457         return error;
0458     return attribute_container_add_attrs(classdev);
0459 }
0460 
0461 /**
0462  * attribute_container_add_class_device_adapter - simple adapter for triggers
0463  *
0464  * @cont: the container to register.
0465  * @dev:  the generic device to activate the trigger for
0466  * @classdev:   the class device to add
0467  *
0468  * This function is identical to attribute_container_add_class_device except
0469  * that it is designed to be called from the triggers
0470  */
0471 int
0472 attribute_container_add_class_device_adapter(struct attribute_container *cont,
0473                          struct device *dev,
0474                          struct device *classdev)
0475 {
0476     return attribute_container_add_class_device(classdev);
0477 }
0478 
0479 /**
0480  * attribute_container_remove_attrs - remove any attribute files
0481  *
0482  * @classdev: The class device to remove the files from
0483  *
0484  */
0485 void
0486 attribute_container_remove_attrs(struct device *classdev)
0487 {
0488     struct attribute_container *cont =
0489         attribute_container_classdev_to_container(classdev);
0490     struct device_attribute **attrs = cont->attrs;
0491     int i;
0492 
0493     if (!attrs && !cont->grp)
0494         return;
0495 
0496     if (cont->grp) {
0497         sysfs_remove_group(&classdev->kobj, cont->grp);
0498         return ;
0499     }
0500 
0501     for (i = 0; attrs[i]; i++)
0502         device_remove_file(classdev, attrs[i]);
0503 }
0504 
0505 /**
0506  * attribute_container_class_device_del - equivalent of class_device_del
0507  *
0508  * @classdev: the class device
0509  *
0510  * This function simply removes all the attribute files and then calls
0511  * device_del.
0512  */
0513 void
0514 attribute_container_class_device_del(struct device *classdev)
0515 {
0516     attribute_container_remove_attrs(classdev);
0517     device_del(classdev);
0518 }
0519 
0520 /**
0521  * attribute_container_find_class_device - find the corresponding class_device
0522  *
0523  * @cont:   the container
0524  * @dev:    the generic device
0525  *
0526  * Looks up the device in the container's list of class devices and returns
0527  * the corresponding class_device.
0528  */
0529 struct device *
0530 attribute_container_find_class_device(struct attribute_container *cont,
0531                       struct device *dev)
0532 {
0533     struct device *cdev = NULL;
0534     struct internal_container *ic;
0535     struct klist_iter iter;
0536 
0537     klist_for_each_entry(ic, &cont->containers, node, &iter) {
0538         if (ic->classdev.parent == dev) {
0539             cdev = &ic->classdev;
0540             /* FIXME: must exit iterator then break */
0541             klist_iter_exit(&iter);
0542             break;
0543         }
0544     }
0545 
0546     return cdev;
0547 }
0548 EXPORT_SYMBOL_GPL(attribute_container_find_class_device);