drivers/s390/cio/vfio_ccw_cp.c
Source file repositories/reference/linux-study-clean/drivers/s390/cio/vfio_ccw_cp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/s390/cio/vfio_ccw_cp.c- Extension
.c- Size
- 25311 bytes
- Lines
- 964
- Domain
- Driver Families
- Bucket
- drivers/s390
- 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.
- 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/ratelimit.hlinux/mm.hlinux/slab.hlinux/highmem.hlinux/iommu.hlinux/vfio.hasm/idals.hvfio_ccw_cp.hvfio_ccw_private.h
Detected Declarations
struct page_arraystruct ccwchainfunction page_array_allocfunction page_array_unpinfunction page_array_pinfunction page_array_unpin_freefunction page_array_iova_pinnedfunction page_array_idal_create_wordsfunction convert_ccw0_to_ccw1function ccw_does_data_transferfunction is_cpa_within_rangefunction is_tic_within_rangefunction ccwchain_freefunction ccwchain_cda_freefunction ccwchain_calc_lengthfunction tic_target_chain_existsfunction list_for_each_entryfunction ccwchain_handle_ccwfunction ccwchain_loop_ticfunction ccwchain_fetch_ticfunction list_for_each_entryfunction ccw_count_idawsfunction ccwchain_fetch_ccwfunction ccwchain_fetch_onefunction cp_initfunction cp_freefunction cp_prefetchfunction list_for_each_entryfunction cp_get_orbfunction cp_update_scswfunction cp_iova_pinnedfunction list_for_each_entry
Annotated Snippet
struct page_array {
/* Array that stores pages need to pin. */
dma_addr_t *pa_iova;
/* Array that receives the pinned pages. */
struct page **pa_page;
/* Number of pages pinned from @pa_iova. */
int pa_nr;
};
struct ccwchain {
struct list_head next;
struct ccw1 *ch_ccw;
/* Guest physical address of the current chain. */
u64 ch_iova;
/* Count of the valid ccws in chain. */
int ch_len;
/* Pinned PAGEs for the original data. */
struct page_array *ch_pa;
};
/*
* page_array_alloc() - alloc memory for page array
* @pa: page_array on which to perform the operation
* @len: number of pages that should be pinned from @iova
*
* Attempt to allocate memory for page array.
*
* Usage of page_array:
* We expect (pa_nr == 0) and (pa_iova == NULL), any field in
* this structure will be filled in by this function.
*
* Returns:
* 0 if page array is allocated
* -EINVAL if pa->pa_nr is not initially zero, or pa->pa_iova is not NULL
* -ENOMEM if alloc failed
*/
static int page_array_alloc(struct page_array *pa, unsigned int len)
{
if (pa->pa_nr || pa->pa_iova)
return -EINVAL;
if (len == 0)
return -EINVAL;
pa->pa_nr = len;
pa->pa_iova = kzalloc_objs(*pa->pa_iova, len);
if (!pa->pa_iova)
return -ENOMEM;
pa->pa_page = kzalloc_objs(*pa->pa_page, len);
if (!pa->pa_page) {
kfree(pa->pa_iova);
return -ENOMEM;
}
return 0;
}
/*
* page_array_unpin() - Unpin user pages in memory
* @pa: page_array on which to perform the operation
* @vdev: the vfio device to perform the operation
* @pa_nr: number of user pages to unpin
* @unaligned: were pages unaligned on the pin request
*
* Only unpin if any pages were pinned to begin with, i.e. pa_nr > 0,
* otherwise only clear pa->pa_nr
*/
static void page_array_unpin(struct page_array *pa,
struct vfio_device *vdev, int pa_nr, bool unaligned)
{
int unpinned = 0, npage = 1;
while (unpinned < pa_nr) {
dma_addr_t *first = &pa->pa_iova[unpinned];
dma_addr_t *last = &first[npage];
if (unpinned + npage < pa_nr &&
*first + npage * PAGE_SIZE == *last &&
!unaligned) {
npage++;
continue;
}
vfio_unpin_pages(vdev, *first, npage);
unpinned += npage;
npage = 1;
}
Annotation
- Immediate include surface: `linux/ratelimit.h`, `linux/mm.h`, `linux/slab.h`, `linux/highmem.h`, `linux/iommu.h`, `linux/vfio.h`, `asm/idals.h`, `vfio_ccw_cp.h`.
- Detected declarations: `struct page_array`, `struct ccwchain`, `function page_array_alloc`, `function page_array_unpin`, `function page_array_pin`, `function page_array_unpin_free`, `function page_array_iova_pinned`, `function page_array_idal_create_words`, `function convert_ccw0_to_ccw1`, `function ccw_does_data_transfer`.
- Atlas domain: Driver Families / drivers/s390.
- 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.