drivers/mtd/chips/cfi_cmdset_0020.c
Source file repositories/reference/linux-study-clean/drivers/mtd/chips/cfi_cmdset_0020.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/chips/cfi_cmdset_0020.c- Extension
.c- Size
- 38321 bytes
- Lines
- 1401
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/types.hlinux/kernel.hlinux/sched.hasm/io.hasm/byteorder.hlinux/errno.hlinux/slab.hlinux/delay.hlinux/interrupt.hlinux/mtd/map.hlinux/mtd/cfi.hlinux/mtd/mtd.h
Detected Declarations
function cfi_tell_featuresfunction do_read_onechipfunction cfi_staa_readfunction do_write_bufferfunction cfi_staa_write_buffersfunction cfi_staa_writevfunction do_erase_oneblockfunction cfi_staa_erase_varsizefunction cfi_staa_syncfunction do_lock_oneblockfunction cfi_staa_lockfunction do_unlock_oneblockfunction cfi_staa_unlockfunction cfi_staa_suspendfunction cfi_staa_resumefunction cfi_staa_destroyexport cfi_cmdset_0020
Annotated Snippet
if (mtd->erasesize < ersize) {
mtd->erasesize = ersize;
}
for (j=0; j<cfi->numchips; j++) {
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
}
offset += (ersize * ernum);
}
if (offset != devsize) {
/* Argh */
printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
kfree(mtd->eraseregions);
goto free_mtd;
}
for (i=0; i<mtd->numeraseregions;i++){
printk(KERN_DEBUG "%d: offset=0x%llx,size=0x%x,blocks=%d\n",
i, (unsigned long long)mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
/* Also select the correct geometry setup too */
mtd->_erase = cfi_staa_erase_varsize;
mtd->_read = cfi_staa_read;
mtd->_write = cfi_staa_write_buffers;
mtd->_writev = cfi_staa_writev;
mtd->_sync = cfi_staa_sync;
mtd->_lock = cfi_staa_lock;
mtd->_unlock = cfi_staa_unlock;
mtd->_suspend = cfi_staa_suspend;
mtd->_resume = cfi_staa_resume;
mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
map->fldrv = &cfi_staa_chipdrv;
__module_get(THIS_MODULE);
mtd->name = map->name;
return mtd;
free_mtd:
kfree(mtd);
free_cmdset_priv:
kfree(cfi->cmdset_priv);
return NULL;
}
static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
{
map_word status, status_OK;
unsigned long timeo;
DECLARE_WAITQUEUE(wait, current);
int suspended = 0;
unsigned long cmd_addr;
struct cfi_private *cfi = map->fldrv_priv;
adr += chip->start;
/* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1);
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
timeo = jiffies + HZ;
retry:
mutex_lock(&chip->mutex);
/* Check that the chip's ready to talk to us.
* If it's in FL_ERASING state, suspend it and make it talk now.
*/
switch (chip->state) {
case FL_ERASING:
if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
goto sleep; /* We don't support erase suspend */
map_write (map, CMD(0xb0), cmd_addr);
/* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to
* 'read' mode. Make sure that we switch to 'read status'
* mode so we get the right data. --rmk
*/
map_write(map, CMD(0x70), cmd_addr);
chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING;
// printk("Erase suspending at 0x%lx\n", cmd_addr);
Annotation
- Immediate include surface: `linux/module.h`, `linux/types.h`, `linux/kernel.h`, `linux/sched.h`, `asm/io.h`, `asm/byteorder.h`, `linux/errno.h`, `linux/slab.h`.
- Detected declarations: `function cfi_tell_features`, `function do_read_onechip`, `function cfi_staa_read`, `function do_write_buffer`, `function cfi_staa_write_buffers`, `function cfi_staa_writev`, `function do_erase_oneblock`, `function cfi_staa_erase_varsize`, `function cfi_staa_sync`, `function do_lock_oneblock`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: integration 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.