lkml.org 
[lkml]   [2007]   [Mar]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 04/22 take 3] UBI: internal header
    diff -auNrp tmp-from/drivers/mtd/ubi/ubi.h tmp-to/drivers/mtd/ubi/ubi.h
    --- tmp-from/drivers/mtd/ubi/ubi.h 1970-01-01 02:00:00.000000000 +0200
    +++ tmp-to/drivers/mtd/ubi/ubi.h 2007-03-14 17:15:50.000000000 +0200
    @@ -0,0 +1,867 @@
    +/*
    + * Copyright (c) International Business Machines Corp., 2006
    + * Copyright (C) Nokia Corporation, 2006, 2007
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
    + * the GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    + *
    + * Author: Artem B. Bityutskiy
    + */
    +
    +#ifndef __UBI_UBI_H__
    +#define __UBI_UBI_H__
    +
    +#include <linux/init.h>
    +#include <linux/types.h>
    +#include <linux/list.h>
    +#include <linux/rbtree.h>
    +#include <linux/sched.h>
    +#include <linux/wait.h>
    +#include <linux/mutex.h>
    +#include <linux/rwsem.h>
    +#include <linux/spinlock.h>
    +#include <linux/fs.h>
    +#include <linux/cdev.h>
    +#include <linux/device.h>
    +#include <linux/string.h>
    +#include <linux/mtd/mtd.h>
    +
    +#include <mtd/ubi-header.h>
    +#include <linux/mtd/ubi.h>
    +
    +#include "debug.h"
    +
    +/* Maximum number UBI devices supported in this implementation */
    +#define UBI_MAX_DEVICES 32
    +
    +/* Name used for UBI character devices, sysfs, etc */
    +#define UBI_STRING_NAME "ubi"
    +
    +/* Normal UBI messages */
    +#define ubi_msg(fmt, ...) \
    + printk(KERN_INFO "UBI: " fmt "\n", ##__VA_ARGS__)
    +/* UBI warning messages */
    +#define ubi_warn(fmt, ...) \
    + printk(KERN_WARNING "UBI warning: %s: " fmt "\n", __FUNCTION__, \
    + ##__VA_ARGS__)
    +/* UBI error messages */
    +#define ubi_err(fmt, ...) \
    + printk(KERN_ERR "UBI error: %s " fmt "\n", __FUNCTION__, \
    + ##__VA_ARGS__)
    +
    +extern int ubis_num;
    +extern struct ubi_info *ubis[];
    +
    +/*
    + * I/O unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +/**
    + * struct ubi_io_info - UBI I/O unit description data structure.
    + *
    + * @flash_size: underlying MTD device size (in bytes)
    + * @peb_count: count of physical eraseblocks on the MTD device
    + * @peb_size: physical eraseblock size
    + * @bad_peb_count: count of bad physical eraseblocks
    + * @good_peb_count: count of good physical eraseblocks
    + * @min_io_size: minimal input/output unit size of the underlying MTD device
    + * @hdrs_min_io_size: minimal I/O unit size used for VID and EC headers
    + * @ro_mode: if the UBI device is in read-only mode
    + * @leb_size: logical eraseblock size
    + * @leb_start: starting offset of logical eraseblocks within physical
    + * eraseblocks
    + * @ec_hdr_alsize: size of the EC header aligned to @hdrs_min_io_size
    + * @vid_hdr_alsize: size of the VID header aligned to @hdrs_min_io_size
    + * @vid_hdr_offset: starting offset of the volume identifier header (might be
    + * unaligned)
    + * @vid_hdr_aloffset: starting offset of the VID header aligned to
    + * @hdrs_min_io_size
    + * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset
    + * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
    + * not
    + * @mtd_num: MTD device number
    + * @mtd_name: MTD device name
    + * @mtd: MTD device descriptor
    + */
    +struct ubi_io_info {
    + long long flash_size; /* public */
    + int peb_count; /* public */
    + int peb_size; /* public */
    + int bad_peb_count; /* public */
    + int good_peb_count; /* public */
    + int min_io_size; /* public */
    + int hdrs_min_io_size; /* public */
    + int ro_mode; /* public */
    + int leb_size; /* public */
    + int leb_start; /* public */
    + int ec_hdr_alsize; /* public */
    + int vid_hdr_alsize; /* public */
    + int vid_hdr_offset; /* public */
    + int vid_hdr_aloffset; /* public */
    + int vid_hdr_shift; /* public */
    + int bad_allowed; /* public */
    + int mtd_num; /* public */
    + const char *mtd_name; /* public */
    + struct mtd_info *mtd; /* private */
    +};
    +
    +/*
    + * Error codes returned by the I/O unit.
    + *
    + * UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only
    + * 0xFF bytes
    + * UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a
    + * valid erase counter header, and the rest are %0xFF bytes
    + * UBI_IO_BAD_EC_HDR: the erase counter header is corrupted (bad magic or CRC)
    + * UBI_IO_BAD_VID_HDR: the volume identifier header is corrupted (bad magic or
    + * CRC)
    + * UBI_IO_BITFLIPS: bit-flips were detected and corrected
    + */
    +enum {
    + UBI_IO_PEB_EMPTY = 1,
    + UBI_IO_PEB_FREE,
    + UBI_IO_BAD_EC_HDR,
    + UBI_IO_BAD_VID_HDR,
    + UBI_IO_BITFLIPS
    +};
    +
    +int ubi_io_read(const struct ubi_info *ubi, void *buf, int pnum, int offset,
    + int len);
    +int ubi_io_write(const struct ubi_info *ubi, const void *buf, int pnum,
    + int offset, int len);
    +int ubi_io_sync_erase(const struct ubi_info *ubi, int pnum, int torture);
    +int ubi_io_is_bad(const struct ubi_info *ubi, int pnum);
    +int ubi_io_mark_bad(const struct ubi_info *ubi, int pnum);
    +int ubi_io_read_ec_hdr(const struct ubi_info *ubi, int pnum,
    + struct ubi_ec_hdr *ec_hdr, int verbose);
    +int ubi_io_write_ec_hdr(const struct ubi_info *ubi, int pnum,
    + struct ubi_ec_hdr *ec_hdr);
    +int ubi_io_read_vid_hdr(const struct ubi_info *ubi, int pnum,
    + struct ubi_vid_hdr *vid_hdr, int verbose);
    +int ubi_io_write_vid_hdr(const struct ubi_info *ubi, int pnum,
    + struct ubi_vid_hdr *vid_hdr);
    +int ubi_io_init(struct ubi_info *ubi, int mtd_num, int vid_hdr_offset,
    + int data_offset);
    +void ubi_io_close(const struct ubi_info *ubi);
    +
    +/*
    + * Scanning unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +/* The erase counter value for this physical eraseblock is unknown */
    +#define NAND_SCAN_UNKNOWN_EC (-1)
    +
    +/* Get sequence number during early initialization stages */
    +#define ubi_scan_next_sqnum(si) (++(si)->max_sqnum)
    +
    +/**
    + * struct ubi_scan_leb - scanning information about a physical eraseblock.
    + *
    + * @ec: erase counter (%NAND_SCAN_UNKNOWN_EC if it is unknown)
    + * @pnum: physical eraseblock number
    + * @lnum: logical eraseblock number
    + * @scrub: if this physical eraseblock needs scrubbing
    + * @sqnum: sequence number
    + * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
    + * @u.list: link in one of the eraseblock lists
    + * @leb_ver: logical eraseblock version (obsolete)
    + *
    + * One object of this type is allocated for each physical eraseblock during
    + * scanning.
    + */
    +struct ubi_scan_leb {
    + int ec;
    + int pnum;
    + int lnum;
    + int scrub;
    + unsigned long long sqnum;
    + union {
    + struct rb_node rb;
    + struct list_head list;
    + } u;
    + uint32_t leb_ver; /* FIXME: obsolete, to be removed */
    +};
    +
    +/**
    + * struct ubi_scan_volume - scanning information about a volume.
    + *
    + * @vol_id: volume ID
    + * @highest_lnum: highest logical eraseblock number in this volume
    + * @leb_count: number of logical eraseblocks in this volume
    + * @vol_type: volume type
    + * @used_ebs: number of used logical eraseblocks in this volume (only for
    + * static volumes)
    + * @last_data_size: amount of data in the last logical eraseblock of this
    + * volume (always equivalent to the usable logical eraseblock size in case of
    + * dynamic volumes)
    + * @data_pad: how many bytes at the end of logical eraseblocks of this volume
    + * are not used (due to volume alignment)
    + * @compat: compatibility flags of this volume
    + * @rb: link in the volume RB-tree
    + * @root: root of the RB-tree containing all the eraseblock belonging to this
    + * volume (&struct ubi_scan_leb objects)
    + *
    + * One object of this type is allocated for each volume during scanning.
    + */
    +struct ubi_scan_volume {
    + int vol_id;
    + int highest_lnum;
    + int leb_count;
    + int vol_type;
    + int used_ebs;
    + int last_data_size;
    + int data_pad;
    + int compat;
    + struct rb_node rb;
    + struct rb_root root;
    +};
    +
    +/**
    + * struct ubi_scan_info - UBI scanning information.
    + *
    + * @volumes: root of the volume RB-tree
    + * @corr: list of corrupted physical eraseblocks
    + * @free: list of free physical eraseblocks
    + * @erase: list of physical eraseblocks which have to be erased
    + * @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
    + * those belonging to "preserve"-compatible internal volumes)
    + * @vols_found: number of volumes found during scanning
    + * @highest_vol_id: highest volume ID
    + * @alien_peb_count: count of physical eraseblocks in the @alien list
    + * @is_empty: flag indicating whether the MTD device is empty or not
    + * @min_ec: lowest erase counter value
    + * @max_ec: highest erase counter value
    + * @max_sqnum: highest sequence number value
    + * @mean_ec: mean erase counter value
    + * @ec_sum: a temporary variable used when calculating @mean_ec
    + * @ec_count: a temporary variable used when calculating @mean_ec
    + *
    + * This data structure contains the result of scanning and may be used by other
    + * UBI units to build final UBI data structures, further error-recovery and so
    + * on.
    + */
    +struct ubi_scan_info {
    + struct rb_root volumes; /* public */
    + struct list_head corr; /* public */
    + struct list_head free; /* public */
    + struct list_head erase; /* public */
    + struct list_head alien; /* public */
    + int vols_found; /* public */
    + int highest_vol_id; /* public */
    + int alien_peb_count; /* public */
    + int is_empty; /* public */
    + int min_ec; /* public */
    + int max_ec; /* public */
    + unsigned long long max_sqnum; /* public */
    + int mean_ec; /* public */
    + int ec_sum; /* private */
    + int ec_count; /* private */
    +};
    +
    +int ubi_scan_add_peb(const struct ubi_info *ubi, struct ubi_scan_info *si,
    + int pnum, int ec, const struct ubi_vid_hdr *vid_hdr,
    + int bitflips);
    +int ubi_scan_add_corr_peb(struct ubi_scan_info *si, int pnum, int ec);
    +struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si,
    + int vol_id);
    +struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv,
    + int lnum);
    +int ubi_scan_erase_peb(const struct ubi_info *ubi,
    + const struct ubi_scan_info *si, int pnum, int ec);
    +struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_info *ubi,
    + struct ubi_scan_info *si);
    +void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv);
    +struct ubi_scan_info *ubi_scan(struct ubi_info *ubi);
    +void ubi_scan_destroy_si(struct ubi_scan_info *si);
    +
    +/*
    + * Volume table unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +/**
    + * struct ubi_vtbl_vtr - in-memory representation of volume table records.
    + *
    + * @reserved_pebs: how many physical eraseblocks are reserved for this volume
    + * @alignment: volume alignment
    + * @data_pad: how many bytes are not used at the end of physical eraseblocks to
    + * satisfy the requested alignment
    + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
    + * @name_len: volume name length
    + * @name: volume name
    + * @usable_leb_size: logical eraseblock size without padding
    + * @used_ebs: how many logical eraseblocks in this volume contain data
    + * @last_eb_bytes: how many bytes are stored in the last logical eraseblock
    + * @used_bytes: how many bytes of data this volume contains
    + * @corrupted: non-zero if the volume is corrupted (static volumes only)
    + * @upd_marker: non-zero if the update marker is set for this volume
    + *
    + * Note, the @usable_leb_size field is not stored on flash, as it is easily
    + * calculated with help of the @data_pad field. But it is just very handy, so
    + * we keep it in the in-RAM volume table record representation. The same is
    + * true for @last_eb_bytes, @used_bytes and @corrupted. We do not store them in
    + * the on-flash volume table but keep handy in RAM.
    + *
    + * The @corrupted field indicates that the volume's contents is corrupted.
    + * Since UBI protects only the contents of static volumes, this field is only
    + * relevant to static volumes. In case of dynamic volumes it is user's
    + * responsibility to assure data integrity.
    + *
    + * The @upd_marker flag indicates that this volume is either being updated at
    + * the moment or is damaged because of an unclean reboot. Note, the @corrupted
    + * flag is always cleared if the @upd_marker flag is set.
    + */
    +struct ubi_vtbl_vtr {
    + int reserved_pebs;
    + int alignment;
    + int data_pad;
    + int vol_type;
    + int name_len;
    + int usable_leb_size;
    + const char *name;
    + int used_ebs;
    + int last_eb_bytes;
    + long long used_bytes;
    + int corrupted;
    + int upd_marker;
    +};
    +
    +/**
    + * struct ubi_vtbl_info - UBI volume table unit description data structure.
    + *
    + * @vt_slots: how many volume table records are stored in the volume table
    + * @vol_count: count of existing volumes
    + * @vt_size: size of the volume table in bytes
    + * @vt: in-RAM copy of the volume table
    + * @ivol_vtrs: volume table records corresponding to internal volumes
    + * @vtbl_lock: protects volume table
    + */
    +struct ubi_vtbl_info {
    + int vt_slots; /* public */
    + int vol_count; /* public */
    + int vt_size; /* private */
    + struct ubi_vtbl_vtr *vt; /* private */
    + struct ubi_vtbl_vtr ivol_vtrs[UBI_INT_VOL_COUNT]; /* private */
    + struct mutex vtbl_lock;
    +};
    +
    +int ubi_vtbl_mkvol(struct ubi_info *ubi, int vol_id, struct ubi_vtbl_vtr *vtr);
    +int ubi_vtbl_rmvol(struct ubi_info *ubi, int vol_id);
    +int ubi_vtbl_rsvol(struct ubi_info *ubi, int vol_id, int reserved_pebs);
    +int ubi_vtbl_set_upd_marker(struct ubi_info *ubi, int vol_id);
    +int ubi_vtbl_clear_upd_marker(struct ubi_info *ubi, int vol_id,
    + long long bytes);
    +int ubi_vtbl_set_corrupted(struct ubi_info *ubi, int vol_id);
    +const struct ubi_vtbl_vtr *ubi_vtbl_get_vtr(const struct ubi_info *ubi,
    + int vol_id);
    +int ubi_vtbl_init_scan(struct ubi_info *ubi, struct ubi_scan_info *si);
    +void ubi_vtbl_close(const struct ubi_info *ubi);
    +
    +/*
    + * Accounting unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +/**
    + * struct ubi_acc_info - UBI accounting unit description data structure.
    + *
    + * @rsvd_pebs: count of reserved physical eraseblocks
    + * @avail_pebs: count of available physical eraseblocks
    + * @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB
    + * handling
    + * @beb_rsvd_max: how many PEBs have to be reserved for bad PEB handling, i.e.,
    + * the normal level of reserved PEBs
    + * @lock: protects @rsvd_pebs, @avail_pebs, @beb_rsvd_pebs, and @beb_rsvd_max
    + */
    +struct ubi_acc_info {
    + int rsvd_pebs; /* public */
    + int avail_pebs; /* public */
    + int beb_rsvd_pebs; /* public */
    + int beb_rsvd_max; /* public */
    + spinlock_t lock; /* private */
    +};
    +
    +int ubi_acc_reserve(struct ubi_info *ubi, int pebs);
    +void ubi_acc_free(struct ubi_info *ubi, int pebs);
    +void ubi_acc_peb_marked_bad(struct ubi_info *ubi);
    +int ubi_acc_init_scan(struct ubi_info *ubi, struct ubi_scan_info *si);
    +
    +/*
    + * Wear-leveling unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +struct ubi_wl_entry;
    +struct ubi_work;
    +
    +/**
    + * struct ubi_wl_info - the UBI wear-leveling unit description data structure.
    + *
    + * @used: RB-tree of used physical eraseblocks
    + * @free: RB-tree of free physical eraseblocks
    + * @scrub: RB-tree of physical eraseblocks which need scrubbing
    + * @prot.pnum: protection tree indexed by physical eraseblock numbers
    + * @prot.aec: protection tree indexed by absolute erase counter value
    + * @lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from,
    + * @move_to, @move_to_put @erase_pending, @wl_scheduled, and @pending_works
    + * fields
    + * @wl_scheduled: non-zero if the wear leveling was scheduled
    + * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any
    + * physical eraseblock
    + * @abs_ec: absolute erase counter
    + * @move_from: physical eraseblock from where the data is being moved
    + * @move_to: physical eraseblock where the data is being moved to
    + * @move_from_put: if the "from" PEB was put
    + * @move_to_put: if the "to" PEB was put
    + * @max_ec: current highest erase counter value
    + * @pending_works: list of pending works
    + * @pending_works_count: count of pending works
    + * @task: pointer to the &struct task_struct of the background thread
    + * @thread_enabled: if the background thread is enabled
    + * @bgt_name: background thread name
    + */
    +struct ubi_wl_info {
    + struct rb_root used; /* private */
    + struct rb_root free; /* private */
    + struct rb_root scrub; /* private */
    + struct {
    + struct rb_root pnum; /* private */
    + struct rb_root aec; /* private */
    + } prot;
    + spinlock_t lock; /* private */
    + int wl_scheduled; /* private */
    + struct ubi_wl_entry **lookuptbl; /* private */
    + unsigned long long abs_ec; /* public */
    + struct ubi_wl_entry *move_from; /* private */
    + struct ubi_wl_entry *move_to; /* private */
    + int move_from_put; /* private */
    + int move_to_put; /* private */
    + int max_ec; /* public */
    + struct list_head pending_works; /* private */
    + int pending_works_count; /* public */
    + struct task_struct *task; /* private */
    + int thread_enabled; /* private */
    + char *bgt_name; /* public */
    +};
    +
    +int ubi_wl_get_peb(struct ubi_info *ubi, enum ubi_data_type dtype);
    +int ubi_wl_put_peb(struct ubi_info *ubi, int pnum, int torture);
    +int ubi_wl_flush(struct ubi_info *ubi);
    +int ubi_wl_scrub_peb(struct ubi_info *ubi, int pnum);
    +void ubi_wl_enable_thread(struct ubi_info *ubi);
    +int ubi_wl_init_scan(struct ubi_info *ubi, struct ubi_scan_info *si);
    +void ubi_wl_close(struct ubi_info *ubi);
    +
    +/*
    + * EBA unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +/**
    + * struct ubi_eba_info - UBI EBA unit description data structure.
    + *
    + * @eba_tbl: the eraseblock association table
    + * @global_sq_cnt: global sequence counter
    + * @eba_tbl_lock: protects the EBA table and the global sequence counter
    + * @ltree: the lock tree
    + * @ltree_lock: protects the lock tree
    + * @num_volumes: number of volumes mapped by the EBA table
    + */
    +struct ubi_eba_info {
    + struct ubi_eba_tbl_volume *eba_tbl; /* private */
    + unsigned long long global_sq_cnt; /* private */
    + spinlock_t eba_tbl_lock; /* private */
    + struct rb_root ltree; /* private */
    + spinlock_t ltree_lock; /* private */
    + int num_volumes; /* private */
    +};
    +
    +int ubi_eba_mkvol(struct ubi_info *ubi, int vol_id, int leb_count);
    +int ubi_eba_rmvol(struct ubi_info *ubi, int vol_id);
    +int ubi_eba_rsvol(struct ubi_info *ubi, int vol_id, int reserved_pebs);
    +int ubi_eba_unmap_leb(struct ubi_info *ubi, int vol_id, int lnum);
    +int ubi_eba_read_leb(struct ubi_info *ubi, int vol_id, int lnum, void *buf,
    + int offset, int len, int check);
    +int ubi_eba_write_leb(struct ubi_info *ubi, int vol_id, int lnum,
    + const void *buf, int offset, int len,
    + enum ubi_data_type dtype);
    +int ubi_eba_write_leb_st(struct ubi_info *ubi, int vol_id, int lnum,
    + const void *buf, int len, enum ubi_data_type dtype,
    + int used_ebs);
    +int ubi_eba_leb_is_mapped(struct ubi_info *ubi, int vol_id, int lnum);
    +void ubi_eba_leb_remap(struct ubi_info *ubi, int vol_id, int lnum, int pnum);
    +int ubi_eba_copy_leb(struct ubi_info *ubi, int from, int to,
    + struct ubi_vid_hdr *vid_hdr);
    +int ubi_eba_init_scan(struct ubi_info *ubi, struct ubi_scan_info *si);
    +void ubi_eba_close(const struct ubi_info *ubi);
    +
    +/*
    + * User-interfaces unit's stuff.
    + *
    + * ============================================================================
    + */
    +
    +struct ubi_vol_desc;
    +
    +/**
    + * struct ubi_uif_volume - UBI volume description data structure.
    + *
    + * @dev: class device object to make use of the the Linux device model
    + * @cdev: Linux character device object to create a character device for this
    + * volume
    + * @ubi: reference to the UBI description object this volume belongs to
    + * @vol_id: volume ID
    + * @list: links volumes belonging to the same UBI device
    + * @readers: number of users holding this volume in read-only mode
    + * @writers: number of users holding this volume in read-write mode
    + * @exclusive: whether somebody holds this volume in exclusive mode
    + * @removed: if the volume was removed from the UBI device
    + * @checked: if this static volume was checked
    + * @vol_lock: protects the @readers, @writers, @exclusive, and @removed fields
    + *
    + * @updating: whether the volume is being updated
    + * @upd_ebs: how many eraseblocks are expected to be updated
    + * @upd_bytes: how many bytes are expected to be received
    + * @upd_received: how many update bytes were already received
    + * @upd_buf: update buffer which is used to collect update data
    + *
    + * @gluebi_desc: gluebi UBI volume descriptor
    + * @gluebi_refcount: reference count of the gluebi MTD device
    + * @gluebi_mtd: MTD device description object of the gluebi MTD device
    + */
    +struct ubi_uif_volume {
    + struct device dev;
    + struct cdev cdev;
    + struct ubi_info *ubi;
    + int vol_id;
    + struct list_head list;
    + int readers;
    + int writers;
    + int exclusive;
    + int removed;
    + int checked;
    + spinlock_t vol_lock;
    +
    + int updating;
    + int upd_ebs;
    + long long upd_bytes;
    + long long upd_received;
    + void *upd_buf;
    +
    +#ifdef CONFIG_MTD_UBI_GLUEBI
    + /* Gluebi-related stuff may be compiled out */
    + struct ubi_vol_desc *gluebi_desc;
    + int gluebi_refcount;
    + struct mtd_info gluebi_mtd;
    +#endif
    +};
    +
    +/**
    + * struct ubi_vol_desc - descriptor of the UBI volume returned when it is
    + * opened.
    + *
    + * @vol: reference to the corresponding volume description object
    + * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE)
    + */
    +struct ubi_vol_desc {
    + struct ubi_uif_volume *vol;
    + int mode;
    +};
    +
    +/**
    + * struct ubi_uif_info - UBI user interfaces unit description structure.
    + *
    + * @cdev: Linux character device object to create a character device of this
    + * UBI device
    + * @dev: class device object to use the the Linux device model
    + * @major: major number of this UBI character device
    + * @volumes: list of 'struct ubi_uif_volume' objects of each volume
    + * @volumes_list_lock: protects the the @volumes list
    + * @vol_check_lock: serializes volume checking
    + * @vol_change_lock: serializes volume creation/deletion/re-sizing
    + * @ubi_name: name of this UBI device
    + *
    + * The @volumes_list_lock lock protects the list of volumes. So it has to be
    + * locked when the @volumes list is being accessed. If @vol->vol_lock has to be
    + * locked simultaneously, @volumes_list_lock is locked first.
    + *
    + * The @vol_check_lock lock is used when checking static volumes consistency to
    + * prevent simultaneous volume checks.
    + *
    + * The volume_change_lock serializes volume creation, deletion and re-sizing,
    + * i.e. it serializes access to the volume table and EBA units.
    + */
    +struct ubi_uif_info {
    + struct cdev cdev;
    + struct device dev;
    + int major;
    + struct list_head volumes;
    + spinlock_t volumes_list_lock;
    + struct mutex vol_check_lock;
    + struct mutex vol_change_lock;
    + char ubi_name[sizeof(UBI_STRING_NAME) + 5];
    +};
    +
    +int ubi_uif_get_exclusive(struct ubi_vol_desc *desc);
    +void ubi_uif_revoke_exclusive(struct ubi_vol_desc *desc, int mode);
    +int ubi_uif_init(struct ubi_info *ubi);
    +void ubi_uif_close(struct ubi_info *ubi);
    +
    +/* The update functionality is implemented in upd.c */
    +int ubi_upd_start(struct ubi_uif_volume *vol, long long bytes);
    +int ubi_upd_write_data(struct ubi_uif_volume *vol, const void __user *buf,
    + int count);
    +void ubi_upd_abort(struct ubi_uif_volume *vol);
    +
    +/* Character device interfaces are implemented in cdev.c */
    +int ubi_cdev_init(struct ubi_info *ubi);
    +void ubi_cdev_close(struct ubi_info *ubi);
    +int ubi_cdev_vol_init(struct ubi_info *ubi, struct ubi_uif_volume *vol);
    +#define ubi_cdev_vol_close(vol) cdev_del(&(vol)->cdev)
    +
    +/* The volume management functionality is implemented at vmt.c */
    +int ubi_vmt_mkvol(struct ubi_info *ubi, int vol_id, struct ubi_vtbl_vtr *vtr);
    +int ubi_vmt_rmvol(struct ubi_vol_desc *desc);
    +int ubi_vmt_rsvol(struct ubi_info *ubi, int vol_id, int reserved_pebs);
    +
    +/* Sysfs support is implemented in sysfs.c */
    +int ubi_sysfs_infr_init(void);
    +void ubi_sysfs_infr_close(void);
    +int ubi_sysfs_init(struct ubi_info *ubi);
    +void ubi_sysfs_close(struct ubi_info *ubi);
    +int ubi_sysfs_vol_init(struct ubi_info *ubi, struct ubi_uif_volume *vol);
    +void ubi_sysfs_vol_close(struct ubi_uif_volume *vol);
    +
    +/* Gluebi stuff is implemented in gluebi.c */
    +#ifdef CONFIG_MTD_UBI_GLUEBI
    +int ubi_gluebi_vol_init(const struct ubi_info *ubi, struct ubi_uif_volume *vol);
    +int ubi_gluebi_vol_close(struct ubi_uif_volume *vol);
    +#else
    +#define ubi_gluebi_vol_init(ubi, vol) 0
    +#define ubi_gluebi_vol_close(vol) 0
    +#endif
    +
    +/**
    + * struct ubi_info - UBI device description structure
    + *
    + * @ubi_num: number of the UBI device
    + * @io: input/output unit information
    + * @wl: wear-leveling unit information
    + * @beb: bad eraseblock handling unit information
    + * @vtbl: volume table unit information
    + * @acc: accounting unit information
    + * @upd: update unit information
    + * @eba: EBA unit information
    + * @uif: user interface unit information
    + */
    +struct ubi_info {
    + int ubi_num;
    + struct ubi_io_info io;
    + struct ubi_wl_info wl;
    + struct ubi_vtbl_info vtbl;
    + struct ubi_acc_info acc;
    + struct ubi_eba_info eba;
    + struct ubi_uif_info uif;
    +};
    +
    +/*
    + * Miscellaneous stuff.
    + *
    + * ============================================================================
    + */
    +
    +/**
    + * rb_for_each_entry - walk an RB-tree.
    + *
    + * @rb: a pointer to type 'struct rb_node' to to use as a loop counter
    + * @pos: a pointer to RB-tree entry type to use as a loop counter
    + * @root: RB-tree's root
    + * @member: the name of the 'struct rb_node' within the RB-tree entry
    + */
    +#define rb_for_each_entry(rb, pos, root, member) \
    + for (rb = rb_first(root), \
    + pos = (rb ? container_of(rb, typeof(*pos), member) : NULL); \
    + rb; \
    + rb = rb_next(rb), pos = container_of(rb, typeof(*pos), member))
    +
    +/*
    + * align_up - align an integer to another integer.
    + *
    + * @x: the integer to align
    + * @y: the integer to align to
    + *
    + * This function returns the lowest number which is multiple to @y and not less
    + * then @x.
    + */
    +static inline int align_up(int x, int y)
    +{
    + return y*(x/y) + (!!(x % y)) * y;
    +}
    +
    +/*
    + * align_down - align an integer to another integer.
    + *
    + * @x: the integer to align
    + * @y: the integer to align to
    + *
    + * This function returns the highest number which is multiple to @y and not
    + * greater then @x.
    + */
    +static inline int align_down(int x, int y)
    +{
    + return y*(x/y);
    +}
    +
    +int ubi_buf_all_ff(const void *buf, int size);
    +int ubi_buf_all_zeroes(const void *buf, int size);
    +int ubi_check_pattern(const void *buf, uint8_t patt, int size);
    +int ubi_calc_data_len(const struct ubi_info *ubi, const void *buf, int length);
    +int ubi_check_volume(struct ubi_info *ubi, int vol_id);
    +
    +/**
    + * ubi_zalloc_vid_hdr - allocate a volume identifier header.
    + *
    + * @ubi: the UBI device description object
    + *
    + * This function returns a pointer to the newly allocated and zero-filled
    + * volume identifier header object in case of success and %NULL in case of
    + * failure.
    + */
    +static inline struct ubi_vid_hdr *ubi_zalloc_vid_hdr(const struct ubi_info *ubi)
    +{
    + void *vid_hdr;
    +
    + vid_hdr = kzalloc(ubi->io.vid_hdr_alsize, GFP_KERNEL);
    + if (unlikely(!vid_hdr))
    + return NULL;
    +
    + /*
    + * If VID headers may be stored at non-aligned flash offsets, so we
    + * shift the pointer to hide alignment complexities from other UBI
    + * units.
    + */
    + return vid_hdr + ubi->io.vid_hdr_shift;
    +}
    +
    +/**
    + * ubi_free_vid_hdr - free a volume identifier header.
    + *
    + * @ubi: the UBI device description object
    + * @vid_hdr: a pointer to the object to free
    + */
    +static inline void ubi_free_vid_hdr(const struct ubi_info *ubi,
    + struct ubi_vid_hdr *vid_hdr)
    +{
    + void *p = vid_hdr;
    +
    + if (unlikely(!p))
    + return;
    + /* The pointer was shifted, shift it back */
    + kfree(p - ubi->io.vid_hdr_shift);
    +}
    +
    +/*
    + * This function is equivalent to 'ubi_io_read()', but @offset is relative to
    + * the beginning of the logical eraseblock, not to the beginning of the
    + * physical eraseblock.
    + */
    +static inline int ubi_io_read_data(const struct ubi_info *ubi, void *buf,
    + int pnum, int offset, int len)
    +{
    + ubi_assert(offset >= 0);
    + return ubi_io_read(ubi, buf, pnum, offset + ubi->io.leb_start, len);
    +}
    +
    +/*
    + * This function is equivalent to 'ubi_io_write()', but @offset is relative to
    + * the beginning of the logical eraseblock, not to the beginning of the
    + * physical eraseblock.
    + */
    +static inline int ubi_io_write_data(const struct ubi_info *ubi, const void *buf,
    + int pnum, int offset, int len)
    +{
    + ubi_assert(offset >= 0);
    + return ubi_io_write(ubi, buf, pnum, offset + ubi->io.leb_start, len);
    +}
    +
    +/**
    + * ubi_ro_mode - switch to read-only mode.
    + *
    + * @ubi: the UBI device description object
    + */
    +static inline void ubi_ro_mode(struct ubi_info *ubi)
    +{
    + ubi->io.ro_mode = 1;
    + ubi_warn("switch to read-only mode");
    +}
    +
    +/**
    + * ubi_is_ivol - check if a volume is an internal volume.
    + *
    + * @vol_id: ID of the volume to test
    + *
    + * If the volume is internal volume, %1 is returned, otherwise %0 is returned.
    + */
    +static inline int ubi_is_ivol(int vol_id)
    +{
    + return vol_id >= UBI_INTERNAL_VOL_START &&
    + vol_id < UBI_INTERNAL_VOL_START + UBI_INT_VOL_COUNT;
    +}
    +
    +/*
    + * ubi_ivol_is_known - check if this is a known internal volume.
    + *
    + * @vol_id: ID of the volume to check.
    + *
    + * This function returns non-zero if this is a known and supported internal
    + * volume and non-zero if not.
    + */
    +static inline int ubi_ivol_is_known(int vol_id)
    +{
    + return vol_id == UBI_LAYOUT_VOL_ID;
    +}
    +
    +/**
    + * ubi_get_compat - get compatibility flags of a volume.
    + *
    + * @ubi: the UBI device description object
    + * @vol_id: volume ID
    + *
    + * This function returns compatibility flags of volumes. User volumes have no
    + * compatibility flags, so %0 is returned. The @vol_id must be correct.
    + */
    +static inline int ubi_get_compat(const struct ubi_info *ubi, int vol_id)
    +{
    + if (!ubi_is_ivol(vol_id))
    + return 0;
    +
    + switch (vol_id) {
    + case UBI_LAYOUT_VOL_ID:
    + return UBI_LAYOUT_VOLUME_COMPAT;
    + default:
    + BUG();
    + }
    +
    + return -ENODEV;
    +}
    +
    +#endif /* !__UBI_UBI_H__ */
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-03-14 16:27    [W:5.367 / U:0.272 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site