# Core MTD routines

- `int add_mtd_device(struct mtd_info *mtd);`
- `int del_mtd_device(struct mtd_info *mtd);`

These routines are called by the hardware driver to register and unregister the device with the MTD subsystem. Each routine returns zero on success, or -ERRNO on failure.

- `struct mtd_info *get_mtd_device(struct mtd_info* mtd, int num);`
- `void put_mtd_device(struct mtd_info *mtd);`

These routines manipulate the use counts of the MTD devices. An MTD device must be locked with `get_mtd_device` before its `struct mtd_info` is dereferenced anywhere outside a notifier `add` function.

`get_mtd_device()` is used to lock devices into memory so that they cannot be unloaded. If invoked with `mtd == NULL`, it will return the MTD device with minor number `num`. If invoked with `num == -1`, it will scan the internal `mtd_table` and return the device with its `struct mtd_info` at location `mtd`. If both `num` and `mtd` are specified, `get_mtd_device` will return successfully only if the entry at location `num` in the `mtd_table` has its `struct mtd_info` at `mtd`.

If the requested device has been removed, or if the arguments do not match, or if the locking fails, then `get_mtd_device` returns `NULL`. If all is successful, it returns the address of the `struct mtd_info` for the locked MTD device.

`put_mtd_device()` is used to unlock the device so that it may subsequently be removed.

- `struct mtd_info *__get_mtd_device(struct mtd_info* mtd, int num);`

This works in a similar fashion to get_mtd_device(), except that it does not perform the locking. It can be used internally by users to obtain MTD devices by number when they know that they have already locked the device in question. It is provided for use by the mtdblock module, and it is not expected to be used anywhere else.

- `int register_mtd_user (struct mtd_notifier *new);`
- `int unregister_mtd_user (struct mtd_notifier *old);`

These routines are called by the user modules, such as the FTL filesystem, which wish to be notified of the addition or removal of physical devices, so they can check for the existence of a filesystem on the device and present or remove the appropriate interface to the user.

They return zero on success, or -ERRNO on failure.

The `struct mtd_notifier` is a simple linked list entry:

        struct mtd_notifier {
            void (*add)(struct mtd_info *mtd);
            void (*remove)(struct mtd_info *mtd);
            struct mtd_notifier *next;
        };

Upon calling `register_mtd_user`, the `add` function of the user will be called for any driver already present in the system. The `add` function will then be called to notify the user of the addition of any further MTD drivers to the system.

Similarly, the `remove` function will be called whenever a driver is removed from the system, and upon calling `unregister_mtd_user`, the `remove` function will be called for any devices which are still present in the system.

The `add` and `remove` functions may sleep, and may call other functions of the MTD device.

NB: Outside the `add` routine, the user may not dereference the `struct mtd_info` about which they have been notified unless they first use `get_mtd_device()` to check that it still exists and increase its use count.

Also note that there is currently no exclusive locking of devices - they may be accessed simultaneously by multiple user modules. An allocation system based on the Linux 2.3 resource trees may be implemented at a later date.

$Id: core.html,v 1.2 2000/05/03 11:44:50 dwmw2 Exp $