STRUCT ATMEL_MCI(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct atmel_mci πŸ’–

okay bestie, welcome to the Kernel API Manual, section 9 β€” this page is literally all about struct atmel_mci, and we're gonna get into every single field without skipping a crumb πŸ“


🌸 NAME 🌸

struct atmel_mci β€” MMC controller state shared between all slots. periodt πŸ’…


✨ SYNOPSIS ✨

struct atmel_mci {
    spinlock_t lock;
    void __iomem            *regs;
    struct scatterlist      *sg;
    unsigned int            sg_len;
    unsigned int            pio_offset;
    unsigned int            *buffer;
    unsigned int            buf_size;
    dma_addr_t buf_phys_addr;
    struct atmel_mci_slot   *cur_slot;
    struct mmc_request      *mrq;
    struct mmc_command      *cmd;
    struct mmc_data         *data;
    unsigned int            data_size;
    struct atmel_mci_dma    dma;
    struct dma_chan         *data_chan;
    struct dma_slave_config dma_conf;
    u32 cmd_status;
    u32 data_status;
    u32 stop_cmdr;
    struct work_struct      bh_work;
    unsigned long           pending_events;
    unsigned long           completed_events;
    enum atmel_mci_state    state;
    struct list_head        queue;
    bool need_clock_update;
    bool need_reset;
    struct timer_list       timer;
    u32 mode_reg;
    u32 cfg_reg;
    unsigned long           bus_hz;
    unsigned long           mapbase;
    struct clk              *mck;
    struct device           *dev;
    struct mci_slot_pdata   pdata[ATMCI_MAX_NR_SLOTS];
    struct atmel_mci_slot   *slot[ATMCI_MAX_NR_SLOTS];
    struct atmel_mci_caps   caps;
    u32 (*prepare_data)(struct atmel_mci *host, struct mmc_data *data);
    void (*submit_data)(struct atmel_mci *host, struct mmc_data *data);
    void (*stop_transfer)(struct atmel_mci *host);
 };

🫢 Members 🫢

  • lock β€” spinlock protecting the queue and associated data, no cap.
  • regs β€” pointer to MMIO registers ✨
  • sg β€” scatterlist entry currently being processed by PIO or PDC code.
  • sg_len β€” size of the scatterlist.
  • pio_offset β€” offset into the current scatterlist entry.
  • buffer β€” buffer used if we don't have the r/w proof capability. We don't have the time to switch pdc buffers so we have to use only one buffer for the full transaction. it's giving efficiency πŸ’€
  • buf_size β€” size of the buffer.
  • buf_phys_addr β€” buffer address needed for pdc.
  • cur_slot β€” the slot which is currently using the controller πŸ‘‘
  • mrq β€” the request currently being processed on cur_slot, or NULL if the controller is idle.
  • cmd β€” the command currently being sent to the card, or NULL.
  • data β€” the data currently being transferred, or NULL if no data transfer is in progress.
  • data_size β€” just data->blocks * data->blksz.
  • dma β€” DMA client state.
  • data_chan β€” DMA channel being used for the current data transfer.
  • dma_conf β€” configuration for the DMA slave.
  • cmd_status β€” snapshot of SR taken upon completion of the current command. Only valid when EVENT_CMD_COMPLETE is pending. iykyk πŸ”₯
  • data_status β€” snapshot of SR taken upon completion of the current data transfer. Only valid when EVENT_DATA_COMPLETE or EVENT_DATA_ERROR is pending.
  • stop_cmdr β€” value to be loaded into CMDR when the stop command is to be sent.
  • bh_work β€” work running the request state machine.
  • pending_events β€” bitmask of events flagged by the interrupt handler to be processed by the work.
  • completed_events β€” bitmask of events which the state machine has processed.
  • state β€” work state.
  • queue β€” list of slots waiting for access to the controller.
  • need_clock_update β€” update the clock rate before the next request.
  • need_reset β€” reset controller before next request.
  • timer β€” timer to balance the data timeout error flag which cannot rise.
  • mode_reg β€” value of the MR register.
  • cfg_reg β€” value of the CFG register.
  • bus_hz β€” the rate of mck in Hz. This forms the basis for MMC bus rate and timeout calculations.
  • mapbase β€” physical address of the MMIO registers.
  • mck β€” the peripheral bus clock hooked up to the MMC controller.
  • dev β€” device associated with the MMC controller.
  • pdata β€” per-slot configuration data.
  • slot β€” slots sharing this MMC controller.
  • caps β€” MCI capabilities depending on MCI version.
  • prepare_data β€” function to setup MCI before data transfer which depends on MCI capabilities.
  • submit_data β€” function to start data transfer which depends on MCI capabilities.
  • stop_transfer β€” function to stop data transfer which depends on MCI capabilities.

πŸ’œ Description πŸ’œ

okay so the whole personality of this struct is locking, and it is not playing around about it 😭

πŸ”’ Locking πŸ”’

lock is a softirq-safe spinlock protecting queue as well as cur_slot, mrq and state. These must always be updated at the same time while holding lock. no splitting the group chat update, bestie 🫢

lock also protects mode_reg and need_clock_update since these are used to synchronize mode register updates with the queue processing.

The mrq field of struct atmel_mci_slot is also protected by lock, and must always be written at the same time as the slot is added to queue.

pending_events and completed_events are accessed using atomic bit operations, so they don't need any locking. slay for them ✨

None of the fields touched by the interrupt handler need any locking. However, ordering is important: Before EVENT_DATA_ERROR or EVENT_DATA_COMPLETE is set in pending_events, all data-related interrupts must be disabled and data_status updated with a snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the CMDRDY interrupt must be disabled and cmd_status updated with a snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the bytes_xfered field of data must be written. This is ensured by using barriers. do not skip the barrier order, fr fr πŸ’€


πŸ¦‹ SEE ALSO πŸ¦‹

  • Kernel file ./drivers/mmc/host/atmel-mci.c
  • struct mci_slot_pdata(9)
  • struct atmel_mci_slot(9)

mwah πŸ’‹ source ./drivers/mmc/host, October 2026, page struct atmel_mci(9) β€” that's the whole footer vibe, bestie 🫢🌈

πŸ“¦ where this page comes from