STRUCT DW_MCI(9)
π struct dw_mci(9) β Kernel API Manual π
β¨ NAME β¨
struct dw_mci β MMC controller state. That's the whole vibe, bestie. π
π¦ SYNOPSIS π¦
struct dw_mci {
spinlock_t lock;
spinlock_t irq_lock;
void __iomem *regs;
void __iomem *fifo_reg;
u32 data_addr_override;
u32 dma_threshold;
bool wm_aligned;
struct scatterlist *sg;
struct sg_mapping_iter sg_miter;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
struct mmc_command stop_abort;
unsigned int prev_blksz;
unsigned char timing;
int use_dma;
int using_dma;
int dma_64bit_address;
dma_addr_t sg_dma;
void *sg_cpu;
const struct dw_mci_dma_ops *dma_ops;
unsigned short desc_num;
struct dw_mci_dma_slave *dms;
resource_size_t phy_regs;
u32 cmd_status;
u32 data_status;
u32 stop_cmdr;
u32 dir_status;
struct work_struct bh_work;
unsigned long pending_events;
unsigned long completed_events;
enum dw_mci_state state;
u32 bus_hz;
u32 current_speed;
u32 minimum_speed;
u32 fifoth_val;
u16 verid;
struct device *dev;
const struct dw_mci_drv_data *drv_data;
void *priv;
struct clk *biu_clk;
struct clk *ciu_clk;
struct dw_mci_slot *slot;
int fifo_depth;
int data_shift;
u8 part_buf_start;
u8 part_buf_count;
union {
u16 part_buf16;
u32 part_buf32;
u64 part_buf;
};
void (*push_data)(struct dw_mci *host, void *buf, int cnt);
void (*pull_data)(struct dw_mci *host, void *buf, int cnt);
u32 quirks;
unsigned long irq_flags;
int irq;
int sdio_irq;
struct timer_list cmd11_timer;
struct timer_list cto_timer;
struct timer_list dto_timer;
#ifdef CONFIG_FAULT_INJECTION;
struct fault_attr fail_data_crc;
struct hrtimer fault_timer;
#endif;
struct mmc_host *mmc;
unsigned long flags;
#define DW_MMC_CARD_NEED_INIT 0;
#define DW_MMC_CARD_NO_LOW_PWR 1;
#define DW_MMC_CARD_NO_USE_HOLD 2;
#define DW_MMC_CARD_NEEDS_POLL 3;
u32 ctype;
unsigned int clock;
unsigned int clk_old;
struct platform_device *pdev;
struct reset_control *rstc;
u32 detect_delay_ms;
struct mmc_clk_phase_map phase_map;
};
πΈ Members πΈ
lockβ spinlock protecting the queue and associated data. πirq_lockβ spinlock protecting theINTMASKsetting. β‘regsβ pointer to MMIO registers.fifo_regβ pointer to MMIO registers for data FIFO. π§Ίdata_addr_overrideβ override fifo reg offset with this value.dma_thresholdβ data threshold value in bytes to carry out a DMA transfer.wm_alignedβ force fifo watermark equal with data length in PIO mode. Set astrueif alignment is needed.sgβ scatterlist entry currently being processed by PIO code, if any.sg_miterβ PIO mapping scatterlist iterator.mrqβ the request currently being processed on host, orNULLif the controller is idle.cmdβ the command currently being sent to the card, orNULL.dataβ the data currently being transferred, orNULLif no data transfer is in progress.stop_abortβ the command currently prepared for stoping transfer.prev_blkszβ the former transferblkszrecord.timingβ record of currentiostiming.use_dmaβ which DMA channel is in use for the current transfer, zero denotes PIO mode. Important, bestie.using_dmaβ whether DMA is in use for the current transfer.dma_64bit_addressβ whether DMA supports 64-bit address mode or not.sg_dmaβ bus address of DMA buffer.sg_cpuβ virtual address of DMA buffer.dma_opsβ pointer to DMA callbacks.desc_numβ number of idmac descriptors available.dmsβ structure of slave-dma private data.phy_regsβ physical address of controller's register map.cmd_statusβ snapshot ofSRtaken upon completion of the current command. Only valid whenEVENT_CMD_COMPLETEis pending.data_statusβ snapshot ofSRtaken upon completion of the current data transfer. Only valid whenEVENT_DATA_COMPLETEorEVENT_DATA_ERRORis pending.stop_cmdrβ value to be loaded intoCMDRwhen the stop command is to be sent.dir_statusβ direction of current transfer.bh_workβ work running the request state machine.pending_eventsβ bitmask of events flagged by the interrupt handler to be processed by bh work.completed_eventsβ bitmask of events which the state machine has processed.stateβ BH work state.bus_hzβ the rate ofmckin Hz. This forms the basis for MMC bus rate and timeout calculations.current_speedβ configured rate of the controller.minimum_speedβ stored minimum rate of the controller.fifoth_valβ the value ofFIFOTHregister.veridβ denote Version ID.devβ device associated with the MMC controller.drv_dataβ driver specific data for identified variant of the controller.privβ implementation defined private data.biu_clkβ pointer to bus interface unit clock instance.ciu_clkβ pointer to card interface unit clock instance.fifo_depthβ depth of FIFO.data_shiftβ log2 of FIFO item size.part_buf_startβ start index inpart_buf.part_buf_countβ bytes of partial data inpart_buf.{unnamed_union}β anonymous.part_bufβ simple buffer for partial fifo reads/writes.push_dataβ pointer to FIFO push function.pull_dataβ pointer to FIFO pull function.quirksβ set of quirks that apply to specific versions of the IP.irq_flagsβ the flags to be passed torequest_irq.irqβ the irq value to be passed torequest_irq.sdio_irqβ SDIO interrupt bit in interrupt registers.cmd11_timerβ timer for SD3.0 voltage switch over scheme.cto_timerβ timer for broken command transfer over scheme.dto_timerβ timer for broken data transfer over scheme.mmcβ themmc_hostrepresenting thisdw_mci.flagsβ random state bits associated with the host.ctypeβ card type for this host.clockβ clock rate configured byset_ios. Protected byhost->lock.clk_oldβ the last clock value that was requested from core.pdevβplatform_deviceregistered.rstcβ reset controller for this host.detect_delay_msβ delay in mS before detecting cards after interrupt.phase_mapβ the map for recording in and out phases for each timing.
π Description π
π Locking π
okay so lock is a softirq-safe spinlock protecting the queue and associated data, plus mrq and state. Those must always be updated at the same time while holding lock. no cap. π₯
irq_lock is an irq-safe spinlock protecting the INTMASK register to allow the interrupt handler to modify it directly. It's held for only long enough to read-modify-write INTMASK, and no other locks are grabbed when holding this one. π
pending_events and completed_events are accessed using atomic bit operations, so they don't need any locking. β¨
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. π§ β¨
π SEE ALSO π
Kernel file ./drivers/mmc/host/dw_mmc.h β go read it, bestie. π«Ά
π source:./drivers/mmc/hostΒ· page:struct dw_mci(9)Β· date: October 2026 Β· Kernel API Manual edition. mwah π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms