drivers/crypto/aspeed/aspeed-hace-hash.c
Source file repositories/reference/linux-study-clean/drivers/crypto/aspeed/aspeed-hace-hash.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/crypto/aspeed/aspeed-hace-hash.c- Extension
.c- Size
- 23770 bytes
- Lines
- 826
- Domain
- Driver Families
- Bucket
- drivers/crypto
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
aspeed-hace.hcrypto/engine.hcrypto/internal/hash.hcrypto/scatterwalk.hcrypto/sha1.hcrypto/sha2.hlinux/dma-mapping.hlinux/err.hlinux/io.hlinux/kernel.hlinux/scatterlist.hlinux/string.h
Detected Declarations
function aspeed_sham_exportfunction aspeed_sham_importfunction bitsfunction aspeed_ahash_update_counterfunction aspeed_ahash_dma_preparefunction aspeed_ahash_dma_prepare_sgfunction aspeed_ahash_completefunction aspeed_hace_ahash_triggerfunction aspeed_ahash_update_resume_sgfunction aspeed_ahash_req_updatefunction aspeed_hace_hash_handle_queuefunction aspeed_ahash_fallbackfunction aspeed_ahash_do_requestfunction aspeed_ahash_prepare_requestfunction aspeed_ahash_do_onefunction aspeed_sham_updatefunction aspeed_sham_finupfunction aspeed_sham_initfunction aspeed_sham_digestfunction aspeed_sham_cra_initfunction aspeed_unregister_hace_hash_algsfunction aspeed_register_hace_hash_algs
Annotated Snippet
else if (rctx->flags & SHA_FLAGS_FINUP) {
if (round_up(length, rctx->block_size) + rctx->block_size >
ASPEED_CRYPTO_SRC_DMA_BUF_LEN)
length = round_down(length - 1, rctx->block_size);
else
final = true;
} else
length -= remain;
memcpy_from_sglist(hash_engine->ahash_src_addr, rctx->src_sg, rctx->offset, length);
aspeed_ahash_update_counter(rctx, length);
if (final)
length += aspeed_ahash_fill_padding(
hace_dev, rctx, hash_engine->ahash_src_addr + length);
rctx->digest_dma_addr = dma_map_single(hace_dev->dev, rctx->digest,
SHA512_DIGEST_SIZE,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(hace_dev->dev, rctx->digest_dma_addr)) {
dev_warn(hace_dev->dev, "dma_map() rctx digest error\n");
return -ENOMEM;
}
hash_engine->src_length = length;
hash_engine->src_dma = hash_engine->ahash_src_dma_addr;
hash_engine->digest_dma = rctx->digest_dma_addr;
return 0;
}
/*
* Prepare DMA buffer as SG list buffer before
* hardware engine processing.
*/
static int aspeed_ahash_dma_prepare_sg(struct aspeed_hace_dev *hace_dev)
{
struct aspeed_engine_hash *hash_engine = &hace_dev->hash_engine;
struct ahash_request *req = hash_engine->req;
struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req);
bool final = rctx->flags & SHA_FLAGS_FINUP;
int remain, sg_len, i, max_sg_nents;
unsigned int length, offset, total;
struct aspeed_sg_list *src_list;
struct scatterlist *s;
int rc = 0;
offset = rctx->offset;
length = rctx->total - offset;
remain = final ? 0 : length - round_down(length, rctx->block_size);
length -= remain;
AHASH_DBG(hace_dev, "%s:0x%x, %s:0x%x, %s:0x%x\n",
"rctx total", rctx->total,
"length", length, "remain", remain);
sg_len = dma_map_sg(hace_dev->dev, rctx->src_sg, rctx->src_nents,
DMA_TO_DEVICE);
if (!sg_len) {
dev_warn(hace_dev->dev, "dma_map_sg() src error\n");
rc = -ENOMEM;
goto end;
}
max_sg_nents = ASPEED_HASH_SRC_DMA_BUF_LEN / sizeof(*src_list) - final;
sg_len = min(sg_len, max_sg_nents);
src_list = (struct aspeed_sg_list *)hash_engine->ahash_src_addr;
rctx->digest_dma_addr = dma_map_single(hace_dev->dev, rctx->digest,
SHA512_DIGEST_SIZE,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(hace_dev->dev, rctx->digest_dma_addr)) {
dev_warn(hace_dev->dev, "dma_map() rctx digest error\n");
rc = -ENOMEM;
goto free_src_sg;
}
total = 0;
for_each_sg(rctx->src_sg, s, sg_len, i) {
u32 phy_addr = sg_dma_address(s);
u32 len = sg_dma_len(s);
if (len <= offset) {
offset -= len;
continue;
}
len -= offset;
phy_addr += offset;
offset = 0;
if (length > len)
length -= len;
Annotation
- Immediate include surface: `aspeed-hace.h`, `crypto/engine.h`, `crypto/internal/hash.h`, `crypto/scatterwalk.h`, `crypto/sha1.h`, `crypto/sha2.h`, `linux/dma-mapping.h`, `linux/err.h`.
- Detected declarations: `function aspeed_sham_export`, `function aspeed_sham_import`, `function bits`, `function aspeed_ahash_update_counter`, `function aspeed_ahash_dma_prepare`, `function aspeed_ahash_dma_prepare_sg`, `function aspeed_ahash_complete`, `function aspeed_hace_ahash_trigger`, `function aspeed_ahash_update_resume_sg`, `function aspeed_ahash_req_update`.
- Atlas domain: Driver Families / drivers/crypto.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.