drivers/mtd/ubi/block.c
Source file repositories/reference/linux-study-clean/drivers/mtd/ubi/block.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/ubi/block.c- Extension
.c- Size
- 15948 bytes
- Lines
- 679
- 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/module.hlinux/init.hlinux/err.hlinux/kernel.hlinux/list.hlinux/mutex.hlinux/slab.hlinux/mtd/ubi.hlinux/blkdev.hlinux/blk-mq.hlinux/hdreg.hlinux/scatterlist.hlinux/idr.hasm/div64.hubi-media.hubi.h
Detected Declarations
struct ubiblock_paramstruct ubiblock_pdustruct ubiblockfunction ubiblock_set_paramfunction ubiblock_readfunction ubiblock_openfunction ubiblock_releasefunction ubiblock_getgeofunction ubiblock_queue_rqfunction ubiblock_init_requestfunction calc_disk_capacityfunction ubiblock_createfunction ubiblock_cleanupfunction ubiblock_removefunction ubiblock_resizefunction match_volume_descfunction ubiblock_create_from_paramfunction ubiblock_notifyfunction ubiblock_remove_allfunction ubiblock_initfunction ubiblock_exit
Annotated Snippet
static const struct blk_mq_ops ubiblock_mq_ops = {
.queue_rq = ubiblock_queue_rq,
.init_request = ubiblock_init_request,
};
static int calc_disk_capacity(struct ubi_volume_info *vi, u64 *disk_capacity)
{
u64 size = vi->used_bytes >> 9;
if (vi->used_bytes % 512) {
if (vi->vol_type == UBI_DYNAMIC_VOLUME)
pr_warn("UBI: block: volume size is not a multiple of 512, last %llu bytes are ignored!\n",
vi->used_bytes - (size << 9));
else
pr_info("UBI: block: volume size is not a multiple of 512, last %llu bytes are ignored!\n",
vi->used_bytes - (size << 9));
}
if ((sector_t)size != size)
return -EFBIG;
*disk_capacity = size;
return 0;
}
int ubiblock_create(struct ubi_volume_info *vi)
{
struct queue_limits lim = {
.max_segments = UBI_MAX_SG_COUNT,
};
struct ubiblock *dev;
struct gendisk *gd;
u64 disk_capacity;
int ret;
ret = calc_disk_capacity(vi, &disk_capacity);
if (ret) {
return ret;
}
/* Check that the volume isn't already handled */
mutex_lock(&devices_mutex);
if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
ret = -EEXIST;
goto out_unlock;
}
dev = kzalloc_obj(struct ubiblock);
if (!dev) {
ret = -ENOMEM;
goto out_unlock;
}
mutex_init(&dev->dev_mutex);
dev->ubi_num = vi->ubi_num;
dev->vol_id = vi->vol_id;
dev->leb_size = vi->usable_leb_size;
dev->tag_set.ops = &ubiblock_mq_ops;
dev->tag_set.queue_depth = 64;
dev->tag_set.numa_node = NUMA_NO_NODE;
dev->tag_set.flags = BLK_MQ_F_BLOCKING;
dev->tag_set.cmd_size = sizeof(struct ubiblock_pdu);
dev->tag_set.driver_data = dev;
dev->tag_set.nr_hw_queues = 1;
ret = blk_mq_alloc_tag_set(&dev->tag_set);
if (ret) {
pr_err("ubiblock%d_%d: blk_mq_alloc_tag_set failed\n",
dev->ubi_num, dev->vol_id);
goto out_free_dev;
}
/* Initialize the gendisk of this ubiblock device */
gd = blk_mq_alloc_disk(&dev->tag_set, &lim, dev);
if (IS_ERR(gd)) {
ret = PTR_ERR(gd);
goto out_free_tags;
}
gd->fops = &ubiblock_ops;
gd->major = ubiblock_major;
gd->minors = 1;
gd->first_minor = idr_alloc(&ubiblock_minor_idr, dev, 0, 0, GFP_KERNEL);
if (gd->first_minor < 0) {
pr_err("ubiblock%d_%d: block: dynamic minor allocation failed\n",
dev->ubi_num, dev->vol_id);
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/err.h`, `linux/kernel.h`, `linux/list.h`, `linux/mutex.h`, `linux/slab.h`, `linux/mtd/ubi.h`.
- Detected declarations: `struct ubiblock_param`, `struct ubiblock_pdu`, `struct ubiblock`, `function ubiblock_set_param`, `function ubiblock_read`, `function ubiblock_open`, `function ubiblock_release`, `function ubiblock_getgeo`, `function ubiblock_queue_rq`, `function ubiblock_init_request`.
- 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.