linux/drivers/mtd/mtdcore.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Core registration and callback routines for MTD
 * drivers and users.
 *
 * Copyright © 1999-2010 David Woodhouse <[email protected]>
 * Copyright © 2006      Red Hat UK Limited 
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/proc_fs.h>
#include <linux/idr.h>
#include <linux/backing-dev.h>
#include <linux/gfp.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <linux/leds.h>
#include <linux/debugfs.h>
#include <linux/nvmem-provider.h>
#include <linux/root_dev.h>
#include <linux/error-injection.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>

#include "mtdcore.h"

struct backing_dev_info *mtd_bdi;

#ifdef CONFIG_PM_SLEEP

static int mtd_cls_suspend(struct device *dev)
{}

static int mtd_cls_resume(struct device *dev)
{}

static SIMPLE_DEV_PM_OPS(mtd_cls_pm_ops, mtd_cls_suspend, mtd_cls_resume);
#define MTD_CLS_PM_OPS
#else
#define MTD_CLS_PM_OPS
#endif

static struct class mtd_class =;

static DEFINE_IDR(mtd_idr);

/* These are exported solely for the purpose of mtd_blkdevs.c. You
   should not use them for _anything_ else */
DEFINE_MUTEX();
EXPORT_SYMBOL_GPL();

struct mtd_info *__mtd_next_device(int i)
{}
EXPORT_SYMBOL_GPL();

static LIST_HEAD(mtd_notifiers);


#define MTD_DEVT(index)

/* REVISIT once MTD uses the driver model better, whoever allocates
 * the mtd_info will probably want to use the release() hook...
 */
static void mtd_release(struct device *dev)
{}

static void mtd_device_release(struct kref *kref)
{}

#define MTD_DEVICE_ATTR_RO(name)

#define MTD_DEVICE_ATTR_RW(name)

static ssize_t mtd_type_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_flags_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_size_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_erasesize_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_writesize_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_subpagesize_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_oobsize_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_oobavail_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_numeraseregions_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_name_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_ecc_strength_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_bitflip_threshold_show(struct device *dev,
					  struct device_attribute *attr,
					  char *buf)
{}

static ssize_t mtd_bitflip_threshold_store(struct device *dev,
					   struct device_attribute *attr,
					   const char *buf, size_t count)
{}
MTD_DEVICE_ATTR_RW();

static ssize_t mtd_ecc_step_size_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_corrected_bits_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();	/* ecc stats corrected */

static ssize_t mtd_ecc_failures_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();	/* ecc stats errors */

static ssize_t mtd_bad_blocks_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static ssize_t mtd_bbt_blocks_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}
MTD_DEVICE_ATTR_RO();

static struct attribute *mtd_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct device_type mtd_devtype =;

static bool mtd_expert_analysis_mode;

#ifdef CONFIG_DEBUG_FS
bool mtd_check_expert_analysis_mode(void)
{}
EXPORT_SYMBOL_GPL();
#endif

static struct dentry *dfs_dir_mtd;

static void mtd_debugfs_populate(struct mtd_info *mtd)
{}

#ifndef CONFIG_MMU
unsigned mtd_mmap_capabilities(struct mtd_info *mtd)
{
	switch (mtd->type) {
	case MTD_RAM:
		return NOMMU_MAP_COPY | NOMMU_MAP_DIRECT | NOMMU_MAP_EXEC |
			NOMMU_MAP_READ | NOMMU_MAP_WRITE;
	case MTD_ROM:
		return NOMMU_MAP_COPY | NOMMU_MAP_DIRECT | NOMMU_MAP_EXEC |
			NOMMU_MAP_READ;
	default:
		return NOMMU_MAP_COPY;
	}
}
EXPORT_SYMBOL_GPL(mtd_mmap_capabilities);
#endif

static int mtd_reboot_notifier(struct notifier_block *n, unsigned long state,
			       void *cmd)
{}

/**
 * mtd_wunit_to_pairing_info - get pairing information of a wunit
 * @mtd: pointer to new MTD device info structure
 * @wunit: write unit we are interested in
 * @info: returned pairing information
 *
 * Retrieve pairing information associated to the wunit.
 * This is mainly useful when dealing with MLC/TLC NANDs where pages can be
 * paired together, and where programming a page may influence the page it is
 * paired with.
 * The notion of page is replaced by the term wunit (write-unit) to stay
 * consistent with the ->writesize field.
 *
 * The @wunit argument can be extracted from an absolute offset using
 * mtd_offset_to_wunit(). @info is filled with the pairing information attached
 * to @wunit.
 *
 * From the pairing info the MTD user can find all the wunits paired with
 * @wunit using the following loop:
 *
 * for (i = 0; i < mtd_pairing_groups(mtd); i++) {
 *	info.pair = i;
 *	mtd_pairing_info_to_wunit(mtd, &info);
 *	...
 * }
 */
int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
			      struct mtd_pairing_info *info)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_pairing_info_to_wunit - get wunit from pairing information
 * @mtd: pointer to new MTD device info structure
 * @info: pairing information struct
 *
 * Returns a positive number representing the wunit associated to the info
 * struct, or a negative error code.
 *
 * This is the reverse of mtd_wunit_to_pairing_info(), and can help one to
 * iterate over all wunits of a given pair (see mtd_wunit_to_pairing_info()
 * doc).
 *
 * It can also be used to only program the first page of each pair (i.e.
 * page attached to group 0), which allows one to use an MLC NAND in
 * software-emulated SLC mode:
 *
 * info.group = 0;
 * npairs = mtd_wunit_per_eb(mtd) / mtd_pairing_groups(mtd);
 * for (info.pair = 0; info.pair < npairs; info.pair++) {
 *	wunit = mtd_pairing_info_to_wunit(mtd, &info);
 *	mtd_write(mtd, mtd_wunit_to_offset(mtd, blkoffs, wunit),
 *		  mtd->writesize, &retlen, buf + (i * mtd->writesize));
 * }
 */
int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
			      const struct mtd_pairing_info *info)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_pairing_groups - get the number of pairing groups
 * @mtd: pointer to new MTD device info structure
 *
 * Returns the number of pairing groups.
 *
 * This number is usually equal to the number of bits exposed by a single
 * cell, and can be used in conjunction with mtd_pairing_info_to_wunit()
 * to iterate over all pages of a given pair.
 */
int mtd_pairing_groups(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

static int mtd_nvmem_reg_read(void *priv, unsigned int offset,
			      void *val, size_t bytes)
{}

static int mtd_nvmem_add(struct mtd_info *mtd)
{}

static void mtd_check_of_node(struct mtd_info *mtd)
{}

/**
 *	add_mtd_device - register an MTD device
 *	@mtd: pointer to new MTD device info structure
 *
 *	Add a device to the list of MTD devices present in the system, and
 *	notify each currently active MTD 'user' of its arrival. Returns
 *	zero on success or non-zero on failure.
 */

int add_mtd_device(struct mtd_info *mtd)
{}

/**
 *	del_mtd_device - unregister an MTD device
 *	@mtd: pointer to MTD device info structure
 *
 *	Remove a device from the list of MTD devices present in the system,
 *	and notify each currently active MTD 'user' of its departure.
 *	Returns zero on success or 1 on failure, which currently will happen
 *	if the requested device does not appear to be present in the list.
 */

int del_mtd_device(struct mtd_info *mtd)
{}

/*
 * Set a few defaults based on the parent devices, if not provided by the
 * driver
 */
static void mtd_set_dev_defaults(struct mtd_info *mtd)
{}

static ssize_t mtd_otp_size(struct mtd_info *mtd, bool is_user)
{}

static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
						   const char *compatible,
						   int size,
						   nvmem_reg_read_t reg_read)
{}

static int mtd_nvmem_user_otp_reg_read(void *priv, unsigned int offset,
				       void *val, size_t bytes)
{}

static int mtd_nvmem_fact_otp_reg_read(void *priv, unsigned int offset,
				       void *val, size_t bytes)
{}

static int mtd_otp_nvmem_add(struct mtd_info *mtd)
{}

/**
 * mtd_device_parse_register - parse partitions and register an MTD device.
 *
 * @mtd: the MTD device to register
 * @types: the list of MTD partition probes to try, see
 *         'parse_mtd_partitions()' for more information
 * @parser_data: MTD partition parser-specific data
 * @parts: fallback partition information to register, if parsing fails;
 *         only valid if %nr_parts > %0
 * @nr_parts: the number of partitions in parts, if zero then the full
 *            MTD device is registered if no partition info is found
 *
 * This function aggregates MTD partitions parsing (done by
 * 'parse_mtd_partitions()') and MTD device and partitions registering. It
 * basically follows the most common pattern found in many MTD drivers:
 *
 * * If the MTD_PARTITIONED_MASTER option is set, then the device as a whole is
 *   registered first.
 * * Then It tries to probe partitions on MTD device @mtd using parsers
 *   specified in @types (if @types is %NULL, then the default list of parsers
 *   is used, see 'parse_mtd_partitions()' for more information). If none are
 *   found this functions tries to fallback to information specified in
 *   @parts/@nr_parts.
 * * If no partitions were found this function just registers the MTD device
 *   @mtd and exits.
 *
 * Returns zero in case of success and a negative error code in case of failure.
 */
int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
			      struct mtd_part_parser_data *parser_data,
			      const struct mtd_partition *parts,
			      int nr_parts)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_device_unregister - unregister an existing MTD device.
 *
 * @master: the MTD device to unregister.  This will unregister both the master
 *          and any partitions if registered.
 */
int mtd_device_unregister(struct mtd_info *master)
{}
EXPORT_SYMBOL_GPL();

/**
 *	register_mtd_user - register a 'user' of MTD devices.
 *	@new: pointer to notifier info structure
 *
 *	Registers a pair of callbacks function to be called upon addition
 *	or removal of MTD devices. Causes the 'add' callback to be immediately
 *	invoked for each MTD device currently present in the system.
 */
void register_mtd_user (struct mtd_notifier *new)
{}
EXPORT_SYMBOL_GPL();

/**
 *	unregister_mtd_user - unregister a 'user' of MTD devices.
 *	@old: pointer to notifier info structure
 *
 *	Removes a callback function pair from the list of 'users' to be
 *	notified upon addition or removal of MTD devices. Causes the
 *	'remove' callback to be immediately invoked for each MTD device
 *	currently present in the system.
 */
int unregister_mtd_user (struct mtd_notifier *old)
{}
EXPORT_SYMBOL_GPL();

/**
 *	get_mtd_device - obtain a validated handle for an MTD device
 *	@mtd: last known address of the required MTD device
 *	@num: internal device number of the required MTD device
 *
 *	Given a number and NULL address, return the num'th entry in the device
 *	table, if any.	Given an address and num == -1, search the device table
 *	for a device with that address and return if it's still present. Given
 *	both, return the num'th driver only if its address matches. Return
 *	error code if not.
 */
struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
{}
EXPORT_SYMBOL_GPL();


int __get_mtd_device(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

/**
 * of_get_mtd_device_by_node - obtain an MTD device associated with a given node
 *
 * @np: device tree node
 */
struct mtd_info *of_get_mtd_device_by_node(struct device_node *np)
{}
EXPORT_SYMBOL_GPL();

/**
 *	get_mtd_device_nm - obtain a validated handle for an MTD device by
 *	device name
 *	@name: MTD device name to open
 *
 * 	This function returns MTD device description structure in case of
 * 	success and an error code in case of failure.
 */
struct mtd_info *get_mtd_device_nm(const char *name)
{}
EXPORT_SYMBOL_GPL();

void put_mtd_device(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

void __put_mtd_device(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

/*
 * Erase is an synchronous operation. Device drivers are epected to return a
 * negative error code if the operation failed and update instr->fail_addr
 * to point the portion that was not properly erased.
 */
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{}
EXPORT_SYMBOL_GPL();
ALLOW_ERROR_INJECTION();

/*
 * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
 */
int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
	      void **virt, resource_size_t *phys)
{}
EXPORT_SYMBOL_GPL();

/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{}
EXPORT_SYMBOL_GPL();

/*
 * Allow NOMMU mmap() to directly map the device (if not NULL)
 * - return the address to which the offset maps
 * - return -ENOSYS to indicate refusal to do the mapping
 */
unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
				    unsigned long offset, unsigned long flags)
{}
EXPORT_SYMBOL_GPL();

static void mtd_update_ecc_stats(struct mtd_info *mtd, struct mtd_info *master,
				 const struct mtd_ecc_stats *old_stats)
{}

int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
	     u_char *buf)
{}
EXPORT_SYMBOL_GPL();
ALLOW_ERROR_INJECTION();

int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
	      const u_char *buf)
{}
EXPORT_SYMBOL_GPL();
ALLOW_ERROR_INJECTION();

/*
 * In blackbox flight recorder like scenarios we want to make successful writes
 * in interrupt context. panic_write() is only intended to be called when its
 * known the kernel is about to panic and we need the write to succeed. Since
 * the kernel is not going to be running for much longer, this function can
 * break locks and delay to ensure the write succeeds (but not sleep).
 */
int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
		    const u_char *buf)
{}
EXPORT_SYMBOL_GPL();

static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs,
			     struct mtd_oob_ops *ops)
{}

static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from,
			    struct mtd_oob_ops *ops)
{}

static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to,
			     struct mtd_oob_ops *ops)
{}

static int mtd_io_emulated_slc(struct mtd_info *mtd, loff_t start, bool read,
			       struct mtd_oob_ops *ops)
{}

int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
{}
EXPORT_SYMBOL_GPL();

int mtd_write_oob(struct mtd_info *mtd, loff_t to,
				struct mtd_oob_ops *ops)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section
 * @mtd: MTD device structure
 * @section: ECC section. Depending on the layout you may have all the ECC
 *	     bytes stored in a single contiguous section, or one section
 *	     per ECC chunk (and sometime several sections for a single ECC
 *	     ECC chunk)
 * @oobecc: OOB region struct filled with the appropriate ECC position
 *	    information
 *
 * This function returns ECC section information in the OOB area. If you want
 * to get all the ECC bytes information, then you should call
 * mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
		      struct mtd_oob_region *oobecc)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_free - Get the OOB region definition of a specific free
 *			section
 * @mtd: MTD device structure
 * @section: Free section you are interested in. Depending on the layout
 *	     you may have all the free bytes stored in a single contiguous
 *	     section, or one section per ECC chunk plus an extra section
 *	     for the remaining bytes (or other funky layout).
 * @oobfree: OOB region struct filled with the appropriate free position
 *	     information
 *
 * This function returns free bytes position in the OOB area. If you want
 * to get all the free bytes information, then you should call
 * mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_free(struct mtd_info *mtd, int section,
		       struct mtd_oob_region *oobfree)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_find_region - Find the region attached to a specific byte
 * @mtd: mtd info structure
 * @byte: the byte we are searching for
 * @sectionp: pointer where the section id will be stored
 * @oobregion: used to retrieve the ECC position
 * @iter: iterator function. Should be either mtd_ooblayout_free or
 *	  mtd_ooblayout_ecc depending on the region type you're searching for
 *
 * This function returns the section id and oobregion information of a
 * specific byte. For example, say you want to know where the 4th ECC byte is
 * stored, you'll use:
 *
 * mtd_ooblayout_find_region(mtd, 3, &section, &oobregion, mtd_ooblayout_ecc);
 *
 * Returns zero on success, a negative error code otherwise.
 */
static int mtd_ooblayout_find_region(struct mtd_info *mtd, int byte,
				int *sectionp, struct mtd_oob_region *oobregion,
				int (*iter)(struct mtd_info *,
					    int section,
					    struct mtd_oob_region *oobregion))
{}

/**
 * mtd_ooblayout_find_eccregion - Find the ECC region attached to a specific
 *				  ECC byte
 * @mtd: mtd info structure
 * @eccbyte: the byte we are searching for
 * @section: pointer where the section id will be stored
 * @oobregion: OOB region information
 *
 * Works like mtd_ooblayout_find_region() except it searches for a specific ECC
 * byte.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
				 int *section,
				 struct mtd_oob_region *oobregion)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_get_bytes - Extract OOB bytes from the oob buffer
 * @mtd: mtd info structure
 * @buf: destination buffer to store OOB bytes
 * @oobbuf: OOB buffer
 * @start: first byte to retrieve
 * @nbytes: number of bytes to retrieve
 * @iter: section iterator
 *
 * Extract bytes attached to a specific category (ECC or free)
 * from the OOB buffer and copy them into buf.
 *
 * Returns zero on success, a negative error code otherwise.
 */
static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf,
				const u8 *oobbuf, int start, int nbytes,
				int (*iter)(struct mtd_info *,
					    int section,
					    struct mtd_oob_region *oobregion))
{}

/**
 * mtd_ooblayout_set_bytes - put OOB bytes into the oob buffer
 * @mtd: mtd info structure
 * @buf: source buffer to get OOB bytes from
 * @oobbuf: OOB buffer
 * @start: first OOB byte to set
 * @nbytes: number of OOB bytes to set
 * @iter: section iterator
 *
 * Fill the OOB buffer with data provided in buf. The category (ECC or free)
 * is selected by passing the appropriate iterator.
 *
 * Returns zero on success, a negative error code otherwise.
 */
static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf,
				u8 *oobbuf, int start, int nbytes,
				int (*iter)(struct mtd_info *,
					    int section,
					    struct mtd_oob_region *oobregion))
{}

/**
 * mtd_ooblayout_count_bytes - count the number of bytes in a OOB category
 * @mtd: mtd info structure
 * @iter: category iterator
 *
 * Count the number of bytes in a given category.
 *
 * Returns a positive value on success, a negative error code otherwise.
 */
static int mtd_ooblayout_count_bytes(struct mtd_info *mtd,
				int (*iter)(struct mtd_info *,
					    int section,
					    struct mtd_oob_region *oobregion))
{}

/**
 * mtd_ooblayout_get_eccbytes - extract ECC bytes from the oob buffer
 * @mtd: mtd info structure
 * @eccbuf: destination buffer to store ECC bytes
 * @oobbuf: OOB buffer
 * @start: first ECC byte to retrieve
 * @nbytes: number of ECC bytes to retrieve
 *
 * Works like mtd_ooblayout_get_bytes(), except it acts on ECC bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
			       const u8 *oobbuf, int start, int nbytes)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_set_eccbytes - set ECC bytes into the oob buffer
 * @mtd: mtd info structure
 * @eccbuf: source buffer to get ECC bytes from
 * @oobbuf: OOB buffer
 * @start: first ECC byte to set
 * @nbytes: number of ECC bytes to set
 *
 * Works like mtd_ooblayout_set_bytes(), except it acts on ECC bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
			       u8 *oobbuf, int start, int nbytes)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_get_databytes - extract data bytes from the oob buffer
 * @mtd: mtd info structure
 * @databuf: destination buffer to store ECC bytes
 * @oobbuf: OOB buffer
 * @start: first ECC byte to retrieve
 * @nbytes: number of ECC bytes to retrieve
 *
 * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
				const u8 *oobbuf, int start, int nbytes)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_set_databytes - set data bytes into the oob buffer
 * @mtd: mtd info structure
 * @databuf: source buffer to get data bytes from
 * @oobbuf: OOB buffer
 * @start: first ECC byte to set
 * @nbytes: number of ECC bytes to set
 *
 * Works like mtd_ooblayout_set_bytes(), except it acts on free bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
				u8 *oobbuf, int start, int nbytes)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_count_freebytes - count the number of free bytes in OOB
 * @mtd: mtd info structure
 *
 * Works like mtd_ooblayout_count_bytes(), except it count free bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_count_freebytes(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_ooblayout_count_eccbytes - count the number of ECC bytes in OOB
 * @mtd: mtd info structure
 *
 * Works like mtd_ooblayout_count_bytes(), except it count ECC bytes.
 *
 * Returns zero on success, a negative error code otherwise.
 */
int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
{}
EXPORT_SYMBOL_GPL();

/*
 * Method to access the protection register area, present in some flash
 * devices. The user data is one time programmable but the factory data is read
 * only.
 */
int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
			   struct otp_info *buf)
{}
EXPORT_SYMBOL_GPL();

int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
			   size_t *retlen, u_char *buf)
{}
EXPORT_SYMBOL_GPL();

int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
			   struct otp_info *buf)
{}
EXPORT_SYMBOL_GPL();

int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
			   size_t *retlen, u_char *buf)
{}
EXPORT_SYMBOL_GPL();

int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
			    size_t *retlen, const u_char *buf)
{}
EXPORT_SYMBOL_GPL();

int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
{}
EXPORT_SYMBOL_GPL();

int mtd_erase_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
{}
EXPORT_SYMBOL_GPL();

/* Chip-supported device locking */
int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{}
EXPORT_SYMBOL_GPL();

int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{}
EXPORT_SYMBOL_GPL();

int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{}
EXPORT_SYMBOL_GPL();

int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs)
{}
EXPORT_SYMBOL_GPL();

int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
{}
EXPORT_SYMBOL_GPL();

int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
{}
EXPORT_SYMBOL_GPL();
ALLOW_ERROR_INJECTION();

/*
 * default_mtd_writev - the default writev method
 * @mtd: mtd device description object pointer
 * @vecs: the vectors to write
 * @count: count of vectors in @vecs
 * @to: the MTD device offset to write to
 * @retlen: on exit contains the count of bytes written to the MTD device.
 *
 * This function returns zero in case of success and a negative error code in
 * case of failure.
 */
static int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
			      unsigned long count, loff_t to, size_t *retlen)
{}

/*
 * mtd_writev - the vector-based MTD write method
 * @mtd: mtd device description object pointer
 * @vecs: the vectors to write
 * @count: count of vectors in @vecs
 * @to: the MTD device offset to write to
 * @retlen: on exit contains the count of bytes written to the MTD device.
 *
 * This function returns zero in case of success and a negative error code in
 * case of failure.
 */
int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
	       unsigned long count, loff_t to, size_t *retlen)
{}
EXPORT_SYMBOL_GPL();

/**
 * mtd_kmalloc_up_to - allocate a contiguous buffer up to the specified size
 * @mtd: mtd device description object pointer
 * @size: a pointer to the ideal or maximum size of the allocation, points
 *        to the actual allocation size on success.
 *
 * This routine attempts to allocate a contiguous kernel buffer up to
 * the specified size, backing off the size of the request exponentially
 * until the request succeeds or until the allocation size falls below
 * the system page size. This attempts to make sure it does not adversely
 * impact system performance, so when allocating more than one page, we
 * ask the memory allocator to avoid re-trying, swapping, writing back
 * or performing I/O.
 *
 * Note, this function also makes sure that the allocated buffer is aligned to
 * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
 *
 * This is called, for example by mtd_{read,write} and jffs2_scan_medium,
 * to handle smaller (i.e. degraded) buffer allocations under low- or
 * fragmented-memory situations where such reduced allocations, from a
 * requested ideal, are allowed.
 *
 * Returns a pointer to the allocated buffer on success; otherwise, NULL.
 */
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_PROC_FS

/*====================================================================*/
/* Support for /proc/mtd */

static int mtd_proc_show(struct seq_file *m, void *v)
{}
#endif /* CONFIG_PROC_FS */

/*====================================================================*/
/* Init code */

static struct backing_dev_info * __init mtd_bdi_init(const char *name)
{}

static struct proc_dir_entry *proc_mtd;

static int __init init_mtd(void)
{}

static void __exit cleanup_mtd(void)
{}

module_init();
module_exit(cleanup_mtd);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();