drivers/mmc/core/sdio_io.c
Source file repositories/reference/linux-study-clean/drivers/mmc/core/sdio_io.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/core/sdio_io.c- Extension
.c- Size
- 21681 bytes
- Lines
- 813
- Domain
- Driver Families
- Bucket
- drivers/mmc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/kernel.hlinux/mmc/host.hlinux/mmc/card.hlinux/mmc/sdio.hlinux/mmc/sdio_func.hsdio_ops.hcore.hcard.hhost.h
Detected Declarations
function sdio_claim_hostfunction sdio_release_hostfunction sdio_enable_funcfunction sdio_disable_funcfunction sdio_set_block_sizefunction sdio_max_byte_sizefunction _sdio_align_sizefunction sdio_align_sizefunction sdio_io_rw_ext_helperfunction sdio_readbfunction sdio_writebfunction RAWfunction sdio_memcpy_fromiofunction sdio_memcpy_toiofunction sdio_readsbfunction sdio_writesbfunction sdio_readwfunction sdio_writewfunction sdio_readlfunction sdio_writelfunction sdio_f0_readbfunction sdio_f0_writebfunction sdio_get_host_pm_capsfunction sdio_get_host_pm_capsfunction commandsfunction sdio_retune_crc_disablefunction sincefunction sdio_retune_hold_nowexport sdio_claim_hostexport sdio_release_hostexport sdio_enable_funcexport sdio_disable_funcexport sdio_set_block_sizeexport sdio_align_sizeexport sdio_readbexport sdio_writebexport sdio_writeb_readbexport sdio_memcpy_fromioexport sdio_memcpy_toioexport sdio_readsbexport sdio_writesbexport sdio_readwexport sdio_writewexport sdio_readlexport sdio_writelexport sdio_f0_readbexport sdio_f0_writebexport sdio_get_host_pm_caps
Annotated Snippet
if (byte_sz <= sdio_max_byte_size(func)) {
blk_sz = sz / func->cur_blksize;
return blk_sz * func->cur_blksize + byte_sz;
}
} else {
/*
* We need multiple requests, so first check that the
* controller can handle the chunk size;
*/
chunk_sz = _sdio_align_size(sdio_max_byte_size(func));
if (chunk_sz == sdio_max_byte_size(func)) {
/*
* Fix up the size of the remainder (if any)
*/
byte_sz = orig_sz % chunk_sz;
if (byte_sz) {
byte_sz = _sdio_align_size(byte_sz);
}
return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
}
}
/*
* The controller is simply incapable of transferring the size
* we want in decent manner, so just return the original size.
*/
return orig_sz;
}
EXPORT_SYMBOL_GPL(sdio_align_size);
/* Split an arbitrarily sized data transfer into several
* IO_RW_EXTENDED commands. */
static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
unsigned addr, int incr_addr, u8 *buf, unsigned size)
{
unsigned remainder = size;
unsigned max_blocks;
int ret;
if (!func || (func->num > 7))
return -EINVAL;
/* Do the bulk of the transfer using block mode (if supported). */
if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
/* Blocks per command is limited by host count, host transfer
* size and the maximum for IO_RW_EXTENDED of 511 blocks. */
max_blocks = min(func->card->host->max_blk_count, 511u);
while (remainder >= func->cur_blksize) {
unsigned blocks;
blocks = remainder / func->cur_blksize;
if (blocks > max_blocks)
blocks = max_blocks;
size = blocks * func->cur_blksize;
ret = mmc_io_rw_extended(func->card, write,
func->num, addr, incr_addr, buf,
blocks, func->cur_blksize);
if (ret)
return ret;
remainder -= size;
buf += size;
if (incr_addr)
addr += size;
}
}
/* Write the remainder using byte mode. */
while (remainder > 0) {
size = min(remainder, sdio_max_byte_size(func));
/* Indicate byte mode by setting "blocks" = 0 */
ret = mmc_io_rw_extended(func->card, write, func->num, addr,
incr_addr, buf, 0, size);
if (ret)
return ret;
remainder -= size;
buf += size;
if (incr_addr)
addr += size;
}
return 0;
}
/**
* sdio_readb - read a single byte from a SDIO function
Annotation
- Immediate include surface: `linux/export.h`, `linux/kernel.h`, `linux/mmc/host.h`, `linux/mmc/card.h`, `linux/mmc/sdio.h`, `linux/mmc/sdio_func.h`, `sdio_ops.h`, `core.h`.
- Detected declarations: `function sdio_claim_host`, `function sdio_release_host`, `function sdio_enable_func`, `function sdio_disable_func`, `function sdio_set_block_size`, `function sdio_max_byte_size`, `function _sdio_align_size`, `function sdio_align_size`, `function sdio_io_rw_ext_helper`, `function sdio_readb`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: integration 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.