drivers/mtd/ubi/fastmap-wl.c

Source file repositories/reference/linux-study-clean/drivers/mtd/ubi/fastmap-wl.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/ubi/fastmap-wl.c
Extension
.c
Size
13898 bytes
Lines
562
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) {
			victim = e;
			max_ec = e->ec;
		}
	}

	return victim;
}

static inline void return_unused_peb(struct ubi_device *ubi,
				     struct ubi_wl_entry *e)
{
	wl_tree_add(e, &ubi->free);
	ubi->free_count++;
}

/**
 * return_unused_pool_pebs - returns unused PEB to the free tree.
 * @ubi: UBI device description object
 * @pool: fastmap pool description object
 */
static void return_unused_pool_pebs(struct ubi_device *ubi,
				    struct ubi_fm_pool *pool)
{
	int i;
	struct ubi_wl_entry *e;

	for (i = pool->used; i < pool->size; i++) {
		e = ubi->lookuptbl[pool->pebs[i]];
		return_unused_peb(ubi, e);
	}
}

/**
 * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number.
 * @ubi: UBI device description object
 * @anchor: This PEB will be used as anchor PEB by fastmap
 *
 * The function returns a physical erase block with a given maximal number
 * and removes it from the wl subsystem.
 * Must be called with wl_lock held!
 */
struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor)
{
	struct ubi_wl_entry *e = NULL;

	if (!ubi->free.rb_node)
		goto out;

	if (anchor)
		e = find_anchor_wl_entry(&ubi->free);
	else
		e = find_mean_wl_entry(ubi, &ubi->free);

	if (!e)
		goto out;

	self_check_in_wl_tree(ubi, e, &ubi->free);

	/* remove it from the free list,
	 * the wl subsystem does no longer know this erase block */
	rb_erase(&e->u.rb, &ubi->free);
	ubi->free_count--;
out:
	return e;
}

/*
 * wait_free_pebs_for_pool - wait until there enough free pebs
 * @ubi: UBI device description object
 *
 * Wait and execute do_work until there are enough free pebs, fill pool
 * as much as we can. This will reduce pool refilling times, which can
 * reduce the fastmap updating frequency.
 */
static void wait_free_pebs_for_pool(struct ubi_device *ubi)
{
	struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
	struct ubi_fm_pool *pool = &ubi->fm_pool;
	int free, expect_free, executed;
	/*
	 * There are at least following free pebs which reserved by UBI:
	 * 1. WL_RESERVED_PEBS[1]
	 * 2. EBA_RESERVED_PEBS[1]
	 * 3. fm pebs - 1: Twice fastmap size deducted by fastmap and fm_anchor
	 * 4. beb_rsvd_pebs: This value should be get under lock ubi->wl_lock
	 */
	int reserved = WL_RESERVED_PEBS + EBA_RESERVED_PEBS +
		       ubi->fm_size / ubi->leb_size - 1 + ubi->fm_pool_rsv_cnt;

Annotation

Implementation Notes