drivers/mmc/host/cb710-mmc.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/cb710-mmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/cb710-mmc.c- Extension
.c- Size
- 22040 bytes
- Lines
- 784
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/pci.hlinux/delay.hlinux/string_choices.hcb710-mmc.h
Detected Declarations
function cb710_mmc_select_clock_dividerfunction __cb710_mmc_enable_irqfunction cb710_mmc_enable_irqfunction cb710_mmc_reset_eventsfunction cb710_mmc_enable_4bit_datafunction cb710_check_eventfunction cb710_wait_for_eventfunction cb710_wait_while_busyfunction cb710_mmc_set_transfer_sizefunction cb710_mmc_fifo_hackfunction cb710_mmc_receive_piofunction cb710_is_transfer_size_supportedfunction cb710_mmc_receivefunction cb710_mmc_sendfunction cb710_encode_cmd_flagsfunction cb710_receive_responsefunction cb710_mmc_transfer_datafunction cb710_mmc_commandfunction cb710_mmc_requestfunction cb710_mmc_powerupfunction cb710_mmc_powerdownfunction cb710_mmc_set_iosfunction cb710_mmc_get_rofunction cb710_mmc_get_cdfunction cb710_mmc_irq_handlerfunction cb710_mmc_finish_request_bh_workfunction cb710_mmc_suspendfunction cb710_mmc_resumefunction cb710_mmc_initfunction cb710_mmc_exit
Annotated Snippet
if (!--limit) {
cb710_dump_regs(cb710_slot_to_chip(slot),
CB710_DUMP_REGS_MMC);
err = -ETIMEDOUT;
break;
}
udelay(1);
}
#ifdef CONFIG_CB710_DEBUG
x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
limit = 2000000 - limit;
if (limit > 100)
dev_dbg(cb710_slot_dev(slot),
"WAIT10: waited %d loops, what %d, entry val %08X, exit val %08X\n",
limit, what, e, x);
#endif
return err < 0 ? err : 0;
}
static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask)
{
unsigned limit = 500000; /* FIXME: real timeout */
int err = 0;
#ifdef CONFIG_CB710_DEBUG
u32 e, x;
e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
#endif
while (cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & mask) {
if (!--limit) {
cb710_dump_regs(cb710_slot_to_chip(slot),
CB710_DUMP_REGS_MMC);
err = -ETIMEDOUT;
break;
}
udelay(1);
}
#ifdef CONFIG_CB710_DEBUG
x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
limit = 500000 - limit;
if (limit > 100)
dev_dbg(cb710_slot_dev(slot),
"WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n",
limit, mask, e, x);
#endif
return err;
}
static void cb710_mmc_set_transfer_size(struct cb710_slot *slot,
size_t count, size_t blocksize)
{
cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
cb710_write_port_32(slot, CB710_MMC_TRANSFER_SIZE_PORT,
((count - 1) << 16)|(blocksize - 1));
dev_vdbg(cb710_slot_dev(slot), "set up for %zu block%s of %zu bytes\n",
count, str_plural(count), blocksize);
}
static void cb710_mmc_fifo_hack(struct cb710_slot *slot)
{
/* without this, received data is prepended with 8-bytes of zeroes */
u32 r1, r2;
int ok = 0;
r1 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
r2 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
if (cb710_read_port_8(slot, CB710_MMC_STATUS0_PORT)
& CB710_MMC_S0_FIFO_UNDERFLOW) {
cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
CB710_MMC_S0_FIFO_UNDERFLOW);
ok = 1;
}
dev_dbg(cb710_slot_dev(slot),
"FIFO-read-hack: expected STATUS0 bit was %s\n",
ok ? "set." : "NOT SET!");
dev_dbg(cb710_slot_dev(slot),
"FIFO-read-hack: dwords ignored: %08X %08X - %s\n",
r1, r2, (r1|r2) ? "BAD (NOT ZERO)!" : "ok");
}
static int cb710_mmc_receive_pio(struct cb710_slot *slot,
struct sg_mapping_iter *miter, size_t dw_count)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/pci.h`, `linux/delay.h`, `linux/string_choices.h`, `cb710-mmc.h`.
- Detected declarations: `function cb710_mmc_select_clock_divider`, `function __cb710_mmc_enable_irq`, `function cb710_mmc_enable_irq`, `function cb710_mmc_reset_events`, `function cb710_mmc_enable_4bit_data`, `function cb710_check_event`, `function cb710_wait_for_event`, `function cb710_wait_while_busy`, `function cb710_mmc_set_transfer_size`, `function cb710_mmc_fifo_hack`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.