drivers/parisc/iommu-helpers.h
Source file repositories/reference/linux-study-clean/drivers/parisc/iommu-helpers.h
File Facts
- System
- Linux kernel
- Corpus path
drivers/parisc/iommu-helpers.h- Extension
.h- Size
- 4848 bytes
- Lines
- 183
- Domain
- Driver Families
- Bucket
- drivers/parisc
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/prefetch.h
Detected Declarations
function iommu_fill_pdirfunction iommu_coalesce_chunks
Annotated Snippet
if (sg_dma_address(startsg) & PIDE_FLAG) {
u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG;
BUG_ON(pdirp && (dma_len != sg_dma_len(dma_sg)));
dma_sg++;
dma_len = sg_dma_len(startsg);
sg_dma_len(startsg) = 0;
dma_offset = (unsigned long) pide & ~IOVP_MASK;
n_mappings++;
#if defined(ZX1_SUPPORT)
/* Pluto IOMMU IO Virt Address is not zero based */
sg_dma_address(dma_sg) = pide | ioc->ibase;
#else
/* SBA, ccio, and dino are zero based.
* Trying to save a few CPU cycles for most users.
*/
sg_dma_address(dma_sg) = pide;
#endif
pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
prefetchw(pdirp);
}
BUG_ON(pdirp == NULL);
paddr = sg_phys(startsg);
sg_dma_len(dma_sg) += startsg->length;
size = startsg->length + dma_offset;
dma_offset = 0;
#ifdef IOMMU_MAP_STATS
ioc->msg_pages += startsg->length >> IOVP_SHIFT;
#endif
do {
iommu_io_pdir_entry(pdirp, KERNEL_SPACE,
paddr, hint);
paddr += IOVP_SIZE;
size -= IOVP_SIZE;
pdirp++;
} while(unlikely(size > 0));
startsg++;
}
return(n_mappings);
}
/*
** First pass is to walk the SG list and determine where the breaks are
** in the DMA stream. Allocates PDIR entries but does not fill them.
** Returns the number of DMA chunks.
**
** Doing the fill separate from the coalescing/allocation keeps the
** code simpler. Future enhancement could make one pass through
** the sglist do both.
*/
static inline unsigned int
iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
struct scatterlist *startsg, int nents,
int (*iommu_alloc_range)(struct ioc *, struct device *, size_t))
{
struct scatterlist *contig_sg; /* contig chunk head */
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
unsigned int n_mappings = 0;
unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
(unsigned)DMA_CHUNK_SIZE);
unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
if (max_seg_boundary) /* check if the addition above didn't overflow */
max_seg_size = min(max_seg_size, max_seg_boundary);
while (nents > 0) {
/*
** Prepare for first/next DMA stream
*/
contig_sg = startsg;
dma_len = startsg->length;
dma_offset = startsg->offset;
/* PARANOID: clear entries */
sg_dma_address(startsg) = 0;
sg_dma_len(startsg) = 0;
/*
** This loop terminates one iteration "early" since
** it's always looking one "ahead".
*/
while(--nents > 0) {
unsigned long prev_end, sg_start;
Annotation
- Immediate include surface: `linux/prefetch.h`.
- Detected declarations: `function iommu_fill_pdir`, `function iommu_coalesce_chunks`.
- Atlas domain: Driver Families / drivers/parisc.
- Implementation status: source 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.