drivers/mtd/mtdblock.c
Source file repositories/reference/linux-study-clean/drivers/mtd/mtdblock.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/mtdblock.c- Extension
.c- Size
- 8965 bytes
- Lines
- 362
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/fs.hlinux/init.hlinux/kernel.hlinux/module.hlinux/sched.hlinux/slab.hlinux/types.hlinux/vmalloc.hlinux/mtd/mtd.hlinux/mtd/blktrans.hlinux/mutex.hlinux/major.h
Detected Declarations
struct mtdblk_devfunction erase_writefunction write_cached_datafunction do_cached_writefunction do_cached_readfunction mtdblock_readsectfunction mtdblock_writesectfunction mtdblock_openfunction mtdblock_releasefunction mtdblock_flushfunction mtdblock_add_mtdfunction mtdblock_remove_dev
Annotated Snippet
struct mtdblk_dev {
struct mtd_blktrans_dev mbd;
int count;
struct mutex cache_mutex;
unsigned char *cache_data;
unsigned long cache_offset;
unsigned int cache_size;
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
};
/*
* Cache stuff...
*
* Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors
* and to speed things up, we locally cache a whole flash sector while it is
* being written to until a different sector is required.
*/
static int erase_write (struct mtd_info *mtd, unsigned long pos,
unsigned int len, const char *buf)
{
struct erase_info erase;
size_t retlen;
int ret;
/*
* First, let's erase the flash block.
*/
erase.addr = pos;
erase.len = len;
ret = mtd_erase(mtd, &erase);
if (ret) {
printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
"on \"%s\" failed\n",
pos, len, mtd->name);
return ret;
}
/*
* Next, write the data to flash.
*/
ret = mtd_write(mtd, pos, len, &retlen, buf);
if (ret)
return ret;
if (retlen != len)
return -EIO;
return 0;
}
static int write_cached_data (struct mtdblk_dev *mtdblk)
{
struct mtd_info *mtd = mtdblk->mbd.mtd;
int ret;
if (mtdblk->cache_state != STATE_DIRTY)
return 0;
pr_debug("mtdblock: writing cached data for \"%s\" "
"at 0x%lx, size 0x%x\n", mtd->name,
mtdblk->cache_offset, mtdblk->cache_size);
ret = erase_write (mtd, mtdblk->cache_offset,
mtdblk->cache_size, mtdblk->cache_data);
/*
* Here we could arguably set the cache state to STATE_CLEAN.
* However this could lead to inconsistency since we will not
* be notified if this content is altered on the flash by other
* means. Let's declare it empty and leave buffering tasks to
* the buffer cache instead.
*
* If this cache_offset points to a bad block, data cannot be
* written to the device. Clear cache_state to avoid writing to
* bad blocks repeatedly.
*/
if (ret == 0 || ret == -EIO)
mtdblk->cache_state = STATE_EMPTY;
return ret;
}
static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
int len, const char *buf)
{
struct mtd_info *mtd = mtdblk->mbd.mtd;
Annotation
- Immediate include surface: `linux/fs.h`, `linux/init.h`, `linux/kernel.h`, `linux/module.h`, `linux/sched.h`, `linux/slab.h`, `linux/types.h`, `linux/vmalloc.h`.
- Detected declarations: `struct mtdblk_dev`, `function erase_write`, `function write_cached_data`, `function do_cached_write`, `function do_cached_read`, `function mtdblock_readsect`, `function mtdblock_writesect`, `function mtdblock_open`, `function mtdblock_release`, `function mtdblock_flush`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.