aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/kapi.c
diff options
context:
space:
mode:
authorDmitry Pervushin <dpervushin@embeddedalley.com>2009-04-29 11:29:38 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-02 06:53:35 -0400
commit0e0ee1cc33de8f0cc603269b354085dee340afa0 (patch)
tree5dfd658b85eabadfbf0c94bee94d46f8d74b839b /drivers/mtd/ubi/kapi.c
parentb86a2c56e512f46d140a4bcb4e35e8a7d4a99a4b (diff)
UBI: add notification API
UBI volume notifications are intended to create the API to get clients notified about volume creation/deletion, renaming and re-sizing. A client can subscribe to these notifications using 'ubi_volume_register()' and cancel the subscription using 'ubi_volume_unregister()'. When UBI volumes change, a blocking notifier is called. Clients also can request "added" events on all volumes that existed before client subscribed to the notifications. If we use notifications instead of calling functions like 'ubi_gluebi_xxx()', we can make the MTD emulation layer to be more flexible: build it as a separate module and load/unload it on demand. [Artem: many cleanups, rework locking, add "updated" event, provide device/volume info in notifiers] Signed-off-by: Dmitry Pervushin <dpervushin@embeddedalley.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/kapi.c')
-rw-r--r--drivers/mtd/ubi/kapi.c108
1 files changed, 92 insertions, 16 deletions
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 2675207c5fe3..88a72e9c8beb 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -26,6 +26,24 @@
26#include "ubi.h" 26#include "ubi.h"
27 27
28/** 28/**
29 * ubi_do_get_device_info - get information about UBI device.
30 * @ubi: UBI device description object
31 * @di: the information is stored here
32 *
33 * This function is the same as 'ubi_get_device_info()', but it assumes the UBI
34 * device is locked and cannot disappear.
35 */
36void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
37{
38 di->ubi_num = ubi->ubi_num;
39 di->leb_size = ubi->leb_size;
40 di->min_io_size = ubi->min_io_size;
41 di->ro_mode = ubi->ro_mode;
42 di->cdev = ubi->cdev.dev;
43}
44EXPORT_SYMBOL_GPL(ubi_do_get_device_info);
45
46/**
29 * ubi_get_device_info - get information about UBI device. 47 * ubi_get_device_info - get information about UBI device.
30 * @ubi_num: UBI device number 48 * @ubi_num: UBI device number
31 * @di: the information is stored here 49 * @di: the information is stored here
@@ -39,33 +57,24 @@ int ubi_get_device_info(int ubi_num, struct ubi_device_info *di)
39 57
40 if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) 58 if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
41 return -EINVAL; 59 return -EINVAL;
42
43 ubi = ubi_get_device(ubi_num); 60 ubi = ubi_get_device(ubi_num);
44 if (!ubi) 61 if (!ubi)
45 return -ENODEV; 62 return -ENODEV;
46 63 ubi_do_get_device_info(ubi, di);
47 di->ubi_num = ubi->ubi_num;
48 di->leb_size = ubi->leb_size;
49 di->min_io_size = ubi->min_io_size;
50 di->ro_mode = ubi->ro_mode;
51 di->cdev = ubi->cdev.dev;
52
53 ubi_put_device(ubi); 64 ubi_put_device(ubi);
54 return 0; 65 return 0;
55} 66}
56EXPORT_SYMBOL_GPL(ubi_get_device_info); 67EXPORT_SYMBOL_GPL(ubi_get_device_info);
57 68
58/** 69/**
59 * ubi_get_volume_info - get information about UBI volume. 70 * ubi_do_get_volume_info - get information about UBI volume.
60 * @desc: volume descriptor 71 * @ubi: UBI device description object
72 * @vol: volume description object
61 * @vi: the information is stored here 73 * @vi: the information is stored here
62 */ 74 */
63void ubi_get_volume_info(struct ubi_volume_desc *desc, 75void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
64 struct ubi_volume_info *vi) 76 struct ubi_volume_info *vi)
65{ 77{
66 const struct ubi_volume *vol = desc->vol;
67 const struct ubi_device *ubi = vol->ubi;
68
69 vi->vol_id = vol->vol_id; 78 vi->vol_id = vol->vol_id;
70 vi->ubi_num = ubi->ubi_num; 79 vi->ubi_num = ubi->ubi_num;
71 vi->size = vol->reserved_pebs; 80 vi->size = vol->reserved_pebs;
@@ -79,6 +88,17 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc,
79 vi->name = vol->name; 88 vi->name = vol->name;
80 vi->cdev = vol->cdev.dev; 89 vi->cdev = vol->cdev.dev;
81} 90}
91
92/**
93 * ubi_get_volume_info - get information about UBI volume.
94 * @desc: volume descriptor
95 * @vi: the information is stored here
96 */
97void ubi_get_volume_info(struct ubi_volume_desc *desc,
98 struct ubi_volume_info *vi)
99{
100 ubi_do_get_volume_info(desc->vol->ubi, desc->vol, vi);
101}
82EXPORT_SYMBOL_GPL(ubi_get_volume_info); 102EXPORT_SYMBOL_GPL(ubi_get_volume_info);
83 103
84/** 104/**
@@ -561,7 +581,7 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
561EXPORT_SYMBOL_GPL(ubi_leb_unmap); 581EXPORT_SYMBOL_GPL(ubi_leb_unmap);
562 582
563/** 583/**
564 * ubi_leb_map - map logical erasblock to a physical eraseblock. 584 * ubi_leb_map - map logical eraseblock to a physical eraseblock.
565 * @desc: volume descriptor 585 * @desc: volume descriptor
566 * @lnum: logical eraseblock number 586 * @lnum: logical eraseblock number
567 * @dtype: expected data type 587 * @dtype: expected data type
@@ -659,3 +679,59 @@ int ubi_sync(int ubi_num)
659 return 0; 679 return 0;
660} 680}
661EXPORT_SYMBOL_GPL(ubi_sync); 681EXPORT_SYMBOL_GPL(ubi_sync);
682
683BLOCKING_NOTIFIER_HEAD(ubi_notifiers);
684
685/**
686 * ubi_register_volume_notifier - register a volume notifier.
687 * @nb: the notifier description object
688 * @ignore_existing: if non-zero, do not send "added" notification for all
689 * already existing volumes
690 *
691 * This function registers a volume notifier, which means that
692 * 'nb->notifier_call()' will be invoked when an UBI volume is created,
693 * removed, re-sized, re-named, or updated. The first argument of the function
694 * is the notification type. The second argument is pointer to a
695 * &struct ubi_notification object which describes the notification event.
696 * Using UBI API from the volume notifier is prohibited.
697 *
698 * This function returns zero in case of success and a negative error code
699 * in case of failure.
700 */
701int ubi_register_volume_notifier(struct notifier_block *nb,
702 int ignore_existing)
703{
704 int err;
705
706 err = blocking_notifier_chain_register(&ubi_notifiers, nb);
707 if (err != 0)
708 return err;
709 if (ignore_existing)
710 return 0;
711
712 /*
713 * We are going to walk all UBI devices and all volumes, and
714 * notify the user about existing volumes by the %UBI_VOLUME_ADDED
715 * event. We have to lock the @ubi_devices_mutex to make sure UBI
716 * devices do not disappear.
717 */
718 mutex_lock(&ubi_devices_mutex);
719 ubi_enumerate_volumes(nb);
720 mutex_unlock(&ubi_devices_mutex);
721
722 return err;
723}
724EXPORT_SYMBOL_GPL(ubi_register_volume_notifier);
725
726/**
727 * ubi_unregister_volume_notifier - unregister the volume notifier.
728 * @nb: the notifier description object
729 *
730 * This function unregisters volume notifier @nm and returns zero in case of
731 * success and a negative error code in case of failure.
732 */
733int ubi_unregister_volume_notifier(struct notifier_block *nb)
734{
735 return blocking_notifier_chain_unregister(&ubi_notifiers, nb);
736}
737EXPORT_SYMBOL_GPL(ubi_unregister_volume_notifier);