xref: /linux/drivers/gpu/drm/i915/i915_scatterlist.c (revision f474808acb3c4b30552d9c59b181244e0300d218)
1 /*
2  * SPDX-License-Identifier: MIT
3  *
4  * Copyright © 2016 Intel Corporation
5  */
6 
7 #include "i915_scatterlist.h"
8 
9 bool i915_sg_trim(struct sg_table *orig_st)
10 {
11 	struct sg_table new_st;
12 	struct scatterlist *sg, *new_sg;
13 	unsigned int i;
14 
15 	if (orig_st->nents == orig_st->orig_nents)
16 		return false;
17 
18 	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
19 		return false;
20 
21 	new_sg = new_st.sgl;
22 	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
23 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
24 		sg_dma_address(new_sg) = sg_dma_address(sg);
25 		sg_dma_len(new_sg) = sg_dma_len(sg);
26 
27 		new_sg = sg_next(new_sg);
28 	}
29 	GEM_BUG_ON(new_sg); /* Should walk exactly nents and hit the end */
30 
31 	sg_free_table(orig_st);
32 
33 	*orig_st = new_st;
34 	return true;
35 }
36 
37 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
38 #include "selftests/scatterlist.c"
39 #endif
40