drivers/dma/fsl_raid.c
Source file repositories/reference/linux-study-clean/drivers/dma/fsl_raid.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/fsl_raid.c- Extension
.c- Size
- 25603 bytes
- Lines
- 895
- Domain
- Driver Families
- Bucket
- drivers/dma
- 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/interrupt.hlinux/module.hlinux/of.hlinux/of_irq.hlinux/of_platform.hlinux/platform_device.hlinux/dma-mapping.hlinux/dmapool.hlinux/dmaengine.hlinux/io.hlinux/spinlock.hlinux/slab.hdmaengine.hfsl_raid.h
Detected Declarations
function Enginefunction fsl_re_issue_pendingfunction list_for_each_entry_safefunction fsl_re_desc_donefunction fsl_re_cleanup_descsfunction fsl_re_dequeuefunction list_for_each_entry_safefunction fsl_re_isrfunction fsl_re_tx_statusfunction fill_cfd_framefunction fsl_re_alloc_chan_resourcesfunction fsl_re_free_chan_resourcesfunction fsl_re_chan_probefunction fsl_re_probefunction for_each_child_of_nodefunction fsl_re_remove_chanfunction fsl_re_remove
Annotated Snippet
if (found) {
fsl_re_desc_done(desc);
list_move_tail(&desc->node, &re_chan->ack_q);
} else {
dev_err(re_chan->dev,
"found hwdesc not in sw queue, discard it\n");
}
oub_count = (re_chan->oub_count + 1) & FSL_RE_RING_SIZE_MASK;
re_chan->oub_count = oub_count;
out_be32(&re_chan->jrregs->oubring_job_rmvd,
FSL_RE_RMVD_JOB(1));
}
spin_unlock_irqrestore(&re_chan->desc_lock, flags);
}
/* Per Job Ring interrupt handler */
static irqreturn_t fsl_re_isr(int irq, void *data)
{
struct fsl_re_chan *re_chan;
u32 irqstate, status;
re_chan = dev_get_drvdata((struct device *)data);
irqstate = in_be32(&re_chan->jrregs->jr_interrupt_status);
if (!irqstate)
return IRQ_NONE;
/*
* There's no way in upper layer (read MD layer) to recover from
* error conditions except restart everything. In long term we
* need to do something more than just crashing
*/
if (irqstate & FSL_RE_ERROR) {
status = in_be32(&re_chan->jrregs->jr_status);
dev_err(re_chan->dev, "chan error irqstate: %x, status: %x\n",
irqstate, status);
}
/* Clear interrupt */
out_be32(&re_chan->jrregs->jr_interrupt_status, FSL_RE_CLR_INTR);
tasklet_schedule(&re_chan->irqtask);
return IRQ_HANDLED;
}
static enum dma_status fsl_re_tx_status(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
return dma_cookie_status(chan, cookie, txstate);
}
static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
size_t length, dma_addr_t addr, bool final)
{
u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
efrl |= final << FSL_RE_CF_FINAL_SHIFT;
cf[index].efrl32 = efrl;
cf[index].addr_high = upper_32_bits(addr);
cf[index].addr_low = lower_32_bits(addr);
}
static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
struct fsl_re_desc *desc,
void *cf, dma_addr_t paddr)
{
desc->re_chan = re_chan;
desc->async_tx.tx_submit = fsl_re_tx_submit;
dma_async_tx_descriptor_init(&desc->async_tx, &re_chan->chan);
INIT_LIST_HEAD(&desc->node);
desc->hwdesc.fmt32 = FSL_RE_FRAME_FORMAT << FSL_RE_HWDESC_FMT_SHIFT;
desc->hwdesc.lbea32 = upper_32_bits(paddr);
desc->hwdesc.addr_low = lower_32_bits(paddr);
desc->cf_addr = cf;
desc->cf_paddr = paddr;
desc->cdb_addr = (void *)(cf + FSL_RE_CF_DESC_SIZE);
desc->cdb_paddr = paddr + FSL_RE_CF_DESC_SIZE;
return desc;
}
static struct fsl_re_desc *fsl_re_chan_alloc_desc(struct fsl_re_chan *re_chan,
unsigned long flags)
{
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/module.h`, `linux/of.h`, `linux/of_irq.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/dma-mapping.h`, `linux/dmapool.h`.
- Detected declarations: `function Engine`, `function fsl_re_issue_pending`, `function list_for_each_entry_safe`, `function fsl_re_desc_done`, `function fsl_re_cleanup_descs`, `function fsl_re_dequeue`, `function list_for_each_entry_safe`, `function fsl_re_isr`, `function fsl_re_tx_status`, `function fill_cfd_frame`.
- Atlas domain: Driver Families / drivers/dma.
- 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.