STRUCT DW_MCI(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– 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 the INTMASK setting. ⚑
  • 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 as true if 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, 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.
  • stop_abort β€” the command currently prepared for stoping transfer.
  • prev_blksz β€” the former transfer blksz record.
  • timing β€” record of current ios timing.
  • 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 of SR taken upon completion of the current command. Only valid when EVENT_CMD_COMPLETE is pending.
  • 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.
  • 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 of mck in 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 of FIFOTH register.
  • 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 in part_buf.
  • part_buf_count β€” bytes of partial data in part_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 to request_irq.
  • irq β€” the irq value to be passed to request_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 β€” the mmc_host representing this dw_mci.
  • flags β€” random state bits associated with the host.
  • ctype β€” card type for this host.
  • clock β€” clock rate configured by set_ios. Protected by host->lock.
  • clk_old β€” the last clock value that was requested from core.
  • pdev β€” platform_device registered.
  • 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