drivers/mtd/parsers/sharpslpart.c
Source file repositories/reference/linux-study-clean/drivers/mtd/parsers/sharpslpart.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/parsers/sharpslpart.c- Extension
.c- Size
- 10830 bytes
- Lines
- 399
- 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.
- 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/types.hlinux/bitops.hlinux/sizes.hlinux/mtd/mtd.hlinux/mtd/partitions.h
Detected Declarations
struct sharpsl_ftlstruct sharpsl_nand_partinfofunction sharpsl_nand_check_ooblayoutfunction sharpsl_nand_read_oobfunction sharpsl_nand_get_logical_numfunction sharpsl_nand_init_ftlfunction sharpsl_nand_cleanup_ftlfunction sharpsl_nand_read_laddrfunction sharpsl_nand_read_partinfofunction be32_to_cpufunction le32_to_cpufunction sharpsl_parse_mtd_partitions
Annotated Snippet
struct sharpsl_ftl {
unsigned int logmax;
unsigned int *log2phy;
};
/* verify that the OOB bytes 8 to 15 are free and available for the FTL */
static int sharpsl_nand_check_ooblayout(struct mtd_info *mtd)
{
u8 freebytes = 0;
int section = 0;
while (true) {
struct mtd_oob_region oobfree = { };
int ret, i;
ret = mtd_ooblayout_free(mtd, section++, &oobfree);
if (ret)
break;
if (!oobfree.length || oobfree.offset > 15 ||
(oobfree.offset + oobfree.length) < 8)
continue;
i = oobfree.offset >= 8 ? oobfree.offset : 8;
for (; i < oobfree.offset + oobfree.length && i < 16; i++)
freebytes |= BIT(i - 8);
if (freebytes == 0xff)
return 0;
}
return -ENOTSUPP;
}
static int sharpsl_nand_read_oob(struct mtd_info *mtd, loff_t offs, u8 *buf)
{
struct mtd_oob_ops ops = { };
int ret;
ops.mode = MTD_OPS_PLACE_OOB;
ops.ooblen = mtd->oobsize;
ops.oobbuf = buf;
ret = mtd_read_oob(mtd, offs, &ops);
if (ret != 0 || mtd->oobsize != ops.oobretlen)
return -1;
return 0;
}
/*
* The logical block number assigned to a physical block is stored in the OOB
* of the first page, in 3 16-bit copies with the following layout:
*
* 01234567 89abcdef
* -------- --------
* ECC BB xyxyxy
*
* When reading we check that the first two copies agree.
* In case of error, matching is tried using the following pairs.
* Reserved values 0xffff mean the block is kept for wear leveling.
*
* 01234567 89abcdef
* -------- --------
* ECC BB xyxy oob[8]==oob[10] && oob[9]==oob[11] -> byte0=8 byte1=9
* ECC BB xyxy oob[10]==oob[12] && oob[11]==oob[13] -> byte0=10 byte1=11
* ECC BB xy xy oob[12]==oob[8] && oob[13]==oob[9] -> byte0=12 byte1=13
*/
static int sharpsl_nand_get_logical_num(u8 *oob)
{
u16 us;
int good0, good1;
if (oob[NAND_NOOB_LOGADDR_00] == oob[NAND_NOOB_LOGADDR_10] &&
oob[NAND_NOOB_LOGADDR_01] == oob[NAND_NOOB_LOGADDR_11]) {
good0 = NAND_NOOB_LOGADDR_00;
good1 = NAND_NOOB_LOGADDR_01;
} else if (oob[NAND_NOOB_LOGADDR_10] == oob[NAND_NOOB_LOGADDR_20] &&
oob[NAND_NOOB_LOGADDR_11] == oob[NAND_NOOB_LOGADDR_21]) {
good0 = NAND_NOOB_LOGADDR_10;
good1 = NAND_NOOB_LOGADDR_11;
} else if (oob[NAND_NOOB_LOGADDR_20] == oob[NAND_NOOB_LOGADDR_00] &&
oob[NAND_NOOB_LOGADDR_21] == oob[NAND_NOOB_LOGADDR_01]) {
good0 = NAND_NOOB_LOGADDR_20;
good1 = NAND_NOOB_LOGADDR_21;
} else {
return -EINVAL;
}
us = oob[good0] | oob[good1] << 8;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/module.h`, `linux/types.h`, `linux/bitops.h`, `linux/sizes.h`, `linux/mtd/mtd.h`, `linux/mtd/partitions.h`.
- Detected declarations: `struct sharpsl_ftl`, `struct sharpsl_nand_partinfo`, `function sharpsl_nand_check_ooblayout`, `function sharpsl_nand_read_oob`, `function sharpsl_nand_get_logical_num`, `function sharpsl_nand_init_ftl`, `function sharpsl_nand_cleanup_ftl`, `function sharpsl_nand_read_laddr`, `function sharpsl_nand_read_partinfo`, `function be32_to_cpu`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
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.