drivers/mtd/mtd_blkdevs.c
Source file repositories/reference/linux-study-clean/drivers/mtd/mtd_blkdevs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/mtd_blkdevs.c- Extension
.c- Size
- 12329 bytes
- Lines
- 543
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/kernel.hlinux/slab.hlinux/module.hlinux/list.hlinux/fs.hlinux/mtd/blktrans.hlinux/mtd/mtd.hlinux/blkdev.hlinux/blk-mq.hlinux/blkpg.hlinux/spinlock.hlinux/hdreg.hlinux/mutex.hlinux/uaccess.hmtdcore.h
Detected Declarations
function blktrans_dev_releasefunction blktrans_dev_putfunction do_blktrans_requestfunction mtd_blktrans_cease_backgroundfunction mtd_blktrans_workfunction mtd_queue_rqfunction blktrans_openfunction blktrans_releasefunction blktrans_getgeofunction add_mtd_blktrans_devfunction list_for_each_entryfunction del_mtd_blktrans_devfunction blktrans_notify_removefunction blktrans_notify_addfunction register_mtd_blktransfunction deregister_mtd_blktransfunction mtd_blktrans_exitexport mtd_blktrans_cease_backgroundexport register_mtd_blktransexport deregister_mtd_blktransexport add_mtd_blktrans_devexport del_mtd_blktrans_dev
Annotated Snippet
static const struct blk_mq_ops mtd_mq_ops = {
.queue_rq = mtd_queue_rq,
};
int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
{
struct mtd_blktrans_ops *tr = new->tr;
struct mtd_blktrans_dev *d;
struct queue_limits lim = { };
int last_devnum = -1;
struct gendisk *gd;
int ret;
lockdep_assert_held(&mtd_table_mutex);
list_for_each_entry(d, &tr->devs, list) {
if (new->devnum == -1) {
/* Use first free number */
if (d->devnum != last_devnum+1) {
/* Found a free devnum. Plug it in here */
new->devnum = last_devnum+1;
list_add_tail(&new->list, &d->list);
goto added;
}
} else if (d->devnum == new->devnum) {
/* Required number taken */
return -EBUSY;
} else if (d->devnum > new->devnum) {
/* Required number was free */
list_add_tail(&new->list, &d->list);
goto added;
}
last_devnum = d->devnum;
}
ret = -EBUSY;
if (new->devnum == -1)
new->devnum = last_devnum+1;
/* Check that the device and any partitions will get valid
* minor numbers and that the disk naming code below can cope
* with this number. */
if (new->devnum > (MINORMASK >> tr->part_bits) ||
(tr->part_bits && new->devnum >= 27 * 26))
return ret;
list_add_tail(&new->list, &tr->devs);
added:
mutex_init(&new->lock);
kref_init(&new->ref);
if (!tr->writesect)
new->readonly = 1;
ret = -ENOMEM;
new->tag_set = kzalloc_obj(*new->tag_set);
if (!new->tag_set)
goto out_list_del;
ret = blk_mq_alloc_sq_tag_set(new->tag_set, &mtd_mq_ops, 2,
BLK_MQ_F_BLOCKING);
if (ret)
goto out_kfree_tag_set;
lim.logical_block_size = tr->blksize;
if (tr->discard)
lim.max_hw_discard_sectors = UINT_MAX;
if (tr->flush)
lim.features |= BLK_FEAT_WRITE_CACHE;
/* Create gendisk */
gd = blk_mq_alloc_disk(new->tag_set, &lim, new);
if (IS_ERR(gd)) {
ret = PTR_ERR(gd);
goto out_free_tag_set;
}
new->disk = gd;
new->rq = new->disk->queue;
gd->private_data = new;
gd->major = tr->major;
gd->first_minor = (new->devnum) << tr->part_bits;
gd->minors = 1 << tr->part_bits;
gd->fops = &mtd_block_ops;
if (tr->part_bits) {
if (new->devnum < 26)
snprintf(gd->disk_name, sizeof(gd->disk_name),
"%s%c", tr->name, 'a' + new->devnum);
else
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/module.h`, `linux/list.h`, `linux/fs.h`, `linux/mtd/blktrans.h`, `linux/mtd/mtd.h`, `linux/blkdev.h`.
- Detected declarations: `function blktrans_dev_release`, `function blktrans_dev_put`, `function do_blktrans_request`, `function mtd_blktrans_cease_background`, `function mtd_blktrans_work`, `function mtd_queue_rq`, `function blktrans_open`, `function blktrans_release`, `function blktrans_getgeo`, `function add_mtd_blktrans_dev`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: pattern 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.