drivers/mmc/core/mmc.c
Source file repositories/reference/linux-study-clean/drivers/mmc/core/mmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/core/mmc.c- Extension
.c- Size
- 66725 bytes
- Lines
- 2465
- Domain
- Driver Families
- Bucket
- drivers/mmc
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/err.hlinux/of.hlinux/slab.hlinux/stat.hlinux/string.hlinux/pm_runtime.hlinux/random.hlinux/sysfs.hlinux/mmc/host.hlinux/mmc/card.hlinux/mmc/mmc.hcore.hcard.hhost.hbus.hmmc_ops.hquirks.hsd_ops.hpwrseq.h
Detected Declarations
enum mmc_poweroff_typefunction mmc_decode_cidfunction mmc_set_erase_sizefunction mmc_set_wp_grp_sizefunction mmc_decode_csdfunction mmc_select_card_typefunction mmc_manage_enhanced_areafunction mmc_part_addfunction mmc_manage_gp_partitionsfunction mmc_decode_ext_csdfunction mmc_read_ext_csdfunction mmc_compare_ext_csdsfunction mmc_fwrev_showfunction mmc_dsr_showfunction __mmc_select_powerclassfunction mmc_select_powerclassfunction mmc_set_bus_speedfunction mmc_select_bus_widthfunction mmc_select_hsfunction mmc_select_hs_ddrfunction mmc_select_hs400function mmc_hs200_to_hs400function mmc_hs400_to_hs200function mmc_select_driver_typefunction mmc_select_hs400esfunction mmc_select_hs200function mmc_select_timingfunction mmc_select_timingfunction mmc_hs200_tuningfunction mmc_init_cardfunction featurefunction mmc_card_can_sleepfunction mmc_sleep_busy_cbfunction mmc_sleepfunction mmc_card_can_poweroff_notifyfunction mmc_host_can_poweroff_notifyfunction mmc_poweroff_notifyfunction mmc_alivefunction mmc_detectfunction _mmc_cache_enabledfunction _mmc_flush_cachefunction _mmc_suspendfunction mmc_removefunction mmc_suspendfunction _mmc_resumefunction mmc_shutdownfunction mmc_resumefunction mmc_runtime_suspend
Annotated Snippet
if (card->ext_csd.partition_setting_completed) {
hc_erase_grp_sz =
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
hc_wp_grp_sz =
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
/*
* calculate the enhanced data area offset, in bytes
*/
card->ext_csd.enhanced_area_offset =
(((unsigned long long)ext_csd[139]) << 24) +
(((unsigned long long)ext_csd[138]) << 16) +
(((unsigned long long)ext_csd[137]) << 8) +
(((unsigned long long)ext_csd[136]));
if (mmc_card_blockaddr(card))
card->ext_csd.enhanced_area_offset <<= 9;
/*
* calculate the enhanced data area size, in kilobytes
*/
card->ext_csd.enhanced_area_size =
(ext_csd[142] << 16) + (ext_csd[141] << 8) +
ext_csd[140];
card->ext_csd.enhanced_area_size *=
(size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
card->ext_csd.enhanced_area_size <<= 9;
} else {
pr_warn("%s: defines enhanced area without partition setting complete\n",
mmc_hostname(card->host));
}
}
}
static void mmc_part_add(struct mmc_card *card, u64 size,
unsigned int part_cfg, char *name, int idx, bool ro,
int area_type)
{
card->part[card->nr_parts].size = size;
card->part[card->nr_parts].part_cfg = part_cfg;
sprintf(card->part[card->nr_parts].name, name, idx);
card->part[card->nr_parts].force_ro = ro;
card->part[card->nr_parts].area_type = area_type;
card->nr_parts++;
}
static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
{
int idx;
u8 hc_erase_grp_sz, hc_wp_grp_sz;
u64 part_size;
/*
* General purpose partition feature support --
* If ext_csd has the size of general purpose partitions,
* set size, part_cfg, partition name in mmc_part.
*/
if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
EXT_CSD_PART_SUPPORT_PART_EN) {
hc_erase_grp_sz =
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
hc_wp_grp_sz =
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
continue;
if (card->ext_csd.partition_setting_completed == 0) {
pr_warn("%s: has partition size defined without partition complete\n",
mmc_hostname(card->host));
break;
}
part_size =
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
<< 16) +
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
<< 8) +
ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
part_size *= (hc_erase_grp_sz * hc_wp_grp_sz);
mmc_part_add(card, part_size << 19,
EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
"gp%d", idx, false,
MMC_BLK_DATA_AREA_GP);
}
}
}
/* Minimum partition switch timeout in milliseconds */
#define MMC_MIN_PART_SWITCH_TIME 300
Annotation
- Immediate include surface: `linux/err.h`, `linux/of.h`, `linux/slab.h`, `linux/stat.h`, `linux/string.h`, `linux/pm_runtime.h`, `linux/random.h`, `linux/sysfs.h`.
- Detected declarations: `enum mmc_poweroff_type`, `function mmc_decode_cid`, `function mmc_set_erase_size`, `function mmc_set_wp_grp_size`, `function mmc_decode_csd`, `function mmc_select_card_type`, `function mmc_manage_enhanced_area`, `function mmc_part_add`, `function mmc_manage_gp_partitions`, `function mmc_decode_ext_csd`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
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.