STRUCT ONENAND_CHIP(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– NAME

struct onenand_chip β€” the OneNAND Private Flash Chip Data, aka the one struct that holds literally everything the kernel needs to gossip with your OneNAND flash chip πŸ’…

okay so real quick before we dive in: this page lives in the Kernel API Manual and it is genuinely giving "one struct to hold the whole entire chip" energy. it ate. it's iconic. periodt. πŸŽ€


✨ SYNOPSIS

struct onenand_chip {
    void __iomem            *base;
    unsigned dies;
    unsigned boundary[MAX_DIES];
    loff_t diesize[MAX_DIES];
    unsigned int            chipsize;
    unsigned int            device_id;
    unsigned int            version_id;
    unsigned int            technology;
    unsigned int            density_mask;
    unsigned int            options;
    unsigned int            badblockpos;
    unsigned int            erase_shift;
    unsigned int            page_shift;
    unsigned int            page_mask;
    unsigned int            writesize;
    unsigned int            bufferram_index;
    struct onenand_bufferram        bufferram[MAX_BUFFERRAM];
    int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
    int (*wait)(struct mtd_info *mtd, int state);
    int (*bbt_wait)(struct mtd_info *mtd, int state);
    void (*unlock_all)(struct mtd_info *mtd);
    int (*read_bufferram)(struct mtd_info *mtd, int area, unsigned char *buffer, int offset, size_t count);
    int (*write_bufferram)(struct mtd_info *mtd, int area, const unsigned char *buffer, int offset, size_t count);
    unsigned short (*read_word)(void __iomem *addr);
    void (*write_word)(unsigned short value, void __iomem *addr);
    void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
    int (*chip_probe)(struct mtd_info *mtd);
    int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
    int (*scan_bbt)(struct mtd_info *mtd);
    int (*enable)(struct mtd_info *mtd);
    int (*disable)(struct mtd_info *mtd);
    struct completion       complete;
    int irq;
    spinlock_t chip_lock;
    wait_queue_head_t wq;
    flstate_t state;
    unsigned char           *page_buf;
    unsigned char           *oob_buf;
  #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE;
    unsigned char           *verify_buf;
  #endif;
    int subpagesize;
    void *bbm;
    void *priv;
    unsigned int            ongoing;
};

lowkey look at all those function pointers 😭 the struct is basically a whole personality made of callbacks πŸ¦‹


🌸 MEMBERS

btw if you're wondering what those lil bracketed tags mean, they're the vibe check on each member β€” [INTERN], [BOARDSPECIFIC], [REPLACEABLE], [OPTIONAL], and [INTERN][FLEX-ONENAND] for the Flex-OneNAND-specific ones. they tell you who's allowed to touch it, iykyk πŸ‘‘

  • base β€” [BOARDSPECIFIC] the address you use to access OneNAND
  • dies β€” [INTERN][FLEX-ONENAND] how many dies are on the chip
  • boundary β€” [INTERN][FLEX-ONENAND] the boundary of the dies
  • diesize β€” [INTERN][FLEX-ONENAND] the size of the dies
  • chipsize β€” [INTERN] the size of one chip for multichip arrays. there's a straight-up FIXME here: for Flex-OneNAND, chipsize holds the maximum possible device size, i.e. when all blocks are considered MLC 🫠
  • device_id β€” [INTERN] the device ID
  • density_mask β€” chip density, used for DDP devices
  • options β€” [BOARDSPECIFIC] various chip options. they can partly be set to inform onenand_scan about stuff
  • erase_shift β€” [INTERN] number of address bits in a block
  • page_shift β€” [INTERN] number of address bits in a page
  • page_mask β€” [INTERN] a page per block mask
  • writesize β€” [INTERN] a real page size
  • bufferram_index β€” [INTERN] BufferRAM index
  • bufferram β€” [INTERN] BufferRAM info
  • command β€” [REPLACEABLE] hardware specific function for writing commands to the chip
  • wait β€” [REPLACEABLE] hardware specific function for wait on ready
  • bbt_wait β€” [REPLACEABLE] hardware specific function for bbt wait on ready
  • unlock_all β€” [REPLACEABLE] hardware specific function for unlock all
  • read_bufferram β€” [REPLACEABLE] hardware specific function for BufferRAM Area
  • write_bufferram β€” [REPLACEABLE] hardware specific function for BufferRAM Area
  • read_word β€” [REPLACEABLE] hardware specific function for read register of OneNAND
  • write_word β€” [REPLACEABLE] hardware specific function for write register of OneNAND
  • mmcontrol β€” sync burst read function
  • chip_probe β€” [REPLACEABLE] hardware specific function for chip probe
  • block_markbad β€” function to mark a block as bad
  • scan_bbt β€” [REPLACEALBE] hardware specific function for scanning Bad block Table (and yes, that spelling is straight from the source, bestie β€” we don't edit the source, we respect the source πŸ’€)
  • chip_lock β€” [INTERN] spinlock used to protect access to this structure and the chip
  • wq β€” [INTERN] wait queue to sleep on if a OneNAND operation is in progress
  • state β€” [INTERN] the current state of the OneNAND device
  • page_buf β€” [INTERN] page main data buffer
  • oob_buf β€” [INTERN] page oob data buffer
  • subpagesize β€” [INTERN] holds the subpagesize
  • bbm β€” [REPLACEABLE] pointer to Bad Block Management
  • priv β€” [OPTIONAL] pointer to private chip date
ngl a couple of the fields up in the struct above don't get their own lil blurb in this Members list β€” version_id, technology, badblockpos, enable, disable, complete, irq and ongoing are just out here living their lives. that's not me gatekeeping, that's literally how the page is written πŸ™ˆ

πŸ¦‹ SEE ALSO

  • Kernel file ./include/linux/mtd/onenand.h
  • struct onenand_bufferram(9)
  • struct onenand_manufacturers(9)

go read those next, bestie, the lore goes deep 🌈


and that's the whole page!! this lil rewrite came to you from the Kernel API Manual, sourced from ./include/linux/mtd, dated October 2026 🫢 stay hydrated, back up your flash, and don't forget to #ifdef your verify_buf πŸ’œβœ¨

πŸ“¦ where this page comes from