drivers/infiniband/hw/cxgb4/mem.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/cxgb4/mem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/cxgb4/mem.c- Extension
.c- Size
- 19919 bytes
- Lines
- 744
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/moduleparam.hlinux/atomic.hrdma/ib_user_verbs.hrdma/iter.hiw_cxgb4.h
Detected Declarations
function mr_exceeds_hw_limitsfunction _c4iw_write_mem_dma_alignedfunction _c4iw_write_mem_inlinefunction _c4iw_write_mem_dmafunction addrfunction write_tpt_entryfunction write_pblfunction dereg_memfunction allocate_stagfunction finish_mem_regfunction register_memfunction alloc_pblfunction rdma_umem_for_each_dma_blockfunction c4iw_set_pagefunction c4iw_map_mr_sgfunction c4iw_dereg_mrfunction c4iw_invalidate_mr
Annotated Snippet
if (!skb) {
skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL);
if (!skb)
return -ENOMEM;
}
set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
req = __skb_put_zero(skb, wr_len);
INIT_ULPTX_WR(req, wr_len, 0, 0);
if (i == (num_wqe-1)) {
req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) |
FW_WR_COMPL_F);
req->wr.wr_lo = (__force __be64)(unsigned long)wr_waitp;
} else
req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR));
req->wr.wr_mid = cpu_to_be32(
FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16)));
req->cmd = cmd;
req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(
DIV_ROUND_UP(copy_len, T4_ULPTX_MIN_IO)));
req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr),
16));
req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(addr + i * 3));
sc = (struct ulptx_idata *)(req + 1);
sc->cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM));
sc->len = cpu_to_be32(roundup(copy_len, T4_ULPTX_MIN_IO));
to_dp = (u8 *)(sc + 1);
from_dp = (u8 *)data + i * C4IW_MAX_INLINE_SIZE;
if (data)
memcpy(to_dp, from_dp, copy_len);
else
memset(to_dp, 0, copy_len);
if (copy_len % T4_ULPTX_MIN_IO)
memset(to_dp + copy_len, 0, T4_ULPTX_MIN_IO -
(copy_len % T4_ULPTX_MIN_IO));
if (i == (num_wqe-1))
ret = c4iw_ref_send_wait(rdev, skb, wr_waitp, 0, 0,
__func__);
else
ret = c4iw_ofld_send(rdev, skb);
if (ret)
break;
skb = NULL;
len -= C4IW_MAX_INLINE_SIZE;
}
return ret;
}
static int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len,
void *data, struct sk_buff *skb,
struct c4iw_wr_wait *wr_waitp)
{
u32 remain = len;
u32 dmalen;
int ret = 0;
dma_addr_t daddr;
dma_addr_t save;
daddr = dma_map_single(&rdev->lldi.pdev->dev, data, len, DMA_TO_DEVICE);
if (dma_mapping_error(&rdev->lldi.pdev->dev, daddr))
return -1;
save = daddr;
while (remain > inline_threshold) {
if (remain < T4_ULPTX_MAX_DMA) {
if (remain & ~T4_ULPTX_MIN_IO)
dmalen = remain & ~(T4_ULPTX_MIN_IO-1);
else
dmalen = remain;
} else
dmalen = T4_ULPTX_MAX_DMA;
remain -= dmalen;
ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, daddr,
skb, remain ? NULL : wr_waitp);
if (ret)
goto out;
addr += dmalen >> 5;
data += dmalen;
daddr += dmalen;
}
if (remain)
ret = _c4iw_write_mem_inline(rdev, addr, remain, data, skb,
wr_waitp);
out:
dma_unmap_single(&rdev->lldi.pdev->dev, save, len, DMA_TO_DEVICE);
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/atomic.h`, `rdma/ib_user_verbs.h`, `rdma/iter.h`, `iw_cxgb4.h`.
- Detected declarations: `function mr_exceeds_hw_limits`, `function _c4iw_write_mem_dma_aligned`, `function _c4iw_write_mem_inline`, `function _c4iw_write_mem_dma`, `function addr`, `function write_tpt_entry`, `function write_pbl`, `function dereg_mem`, `function allocate_stag`, `function finish_mem_reg`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.