drivers/gpu/drm/i915/selftests/scatterlist.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/selftests/scatterlist.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/selftests/scatterlist.c
Extension
.c
Size
9343 bytes
Lines
385
Domain
Driver Families
Bucket
drivers/gpu
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pfn_table {
	struct sg_table st;
	unsigned long start, end;
};

typedef unsigned int (*npages_fn_t)(unsigned long n,
				    unsigned long count,
				    struct rnd_state *rnd);

static noinline int expect_pfn_sg(struct pfn_table *pt,
				  npages_fn_t npages_fn,
				  struct rnd_state *rnd,
				  const char *who,
				  unsigned long timeout)
{
	struct scatterlist *sg;
	unsigned long pfn, n;

	pfn = pt->start;
	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
		struct page *page = sg_page(sg);
		unsigned int npages = npages_fn(n, pt->st.nents, rnd);

		if (page_to_pfn(page) != pfn) {
			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
			       __func__, who, pfn, page_to_pfn(page));
			return -EINVAL;
		}

		if (sg->length != npages * PAGE_SIZE) {
			pr_err("%s: %s copied wrong sg length, expected size %lu, found %u (using for_each_sg)\n",
			       __func__, who, npages * PAGE_SIZE, sg->length);
			return -EINVAL;
		}

		if (igt_timeout(timeout, "%s timed out\n", who))
			return -EINTR;

		pfn += npages;
	}
	if (pfn != pt->end) {
		pr_err("%s: %s finished on wrong pfn, expected %lu, found %lu\n",
		       __func__, who, pt->end, pfn);
		return -EINVAL;
	}

	return 0;
}

static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
					    const char *who,
					    unsigned long timeout)
{
	struct sg_page_iter sgiter;
	unsigned long pfn;

	pfn = pt->start;
	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
		struct page *page = sg_page_iter_page(&sgiter);

		if (page != pfn_to_page(pfn)) {
			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg_page)\n",
			       __func__, who, pfn, page_to_pfn(page));
			return -EINVAL;
		}

		if (igt_timeout(timeout, "%s timed out\n", who))
			return -EINTR;

		pfn++;
	}
	if (pfn != pt->end) {
		pr_err("%s: %s finished on wrong pfn, expected %lu, found %lu\n",
		       __func__, who, pt->end, pfn);
		return -EINVAL;
	}

	return 0;
}

static noinline int expect_pfn_sgtiter(struct pfn_table *pt,
				       const char *who,
				       unsigned long timeout)
{
	struct sgt_iter sgt;
	struct page *page;
	unsigned long pfn;

	pfn = pt->start;
	for_each_sgt_page(page, sgt, &pt->st) {

Annotation

Implementation Notes