1 #include <stdio.h> 2 #include <assert.h> 3 4 #include <linux/scatterlist.h> 5 6 #define MAX_PAGES (64) 7 8 static void set_pages(struct page **pages, const unsigned *array, unsigned num) 9 { 10 unsigned int i; 11 12 assert(num < MAX_PAGES); 13 for (i = 0; i < num; i++) 14 pages[i] = (struct page *)(unsigned long) 15 ((1 + array[i]) * PAGE_SIZE); 16 } 17 18 #define pfn(...) (unsigned []){ __VA_ARGS__ } 19 20 int main(void) 21 { 22 const unsigned int sgmax = SCATTERLIST_MAX_SEGMENT; 23 struct test { 24 int alloc_ret; 25 unsigned num_pages; 26 unsigned *pfn; 27 unsigned size; 28 unsigned int max_seg; 29 unsigned int expected_segments; 30 } *test, tests[] = { 31 { -EINVAL, 1, pfn(0), PAGE_SIZE, PAGE_SIZE + 1, 1 }, 32 { -EINVAL, 1, pfn(0), PAGE_SIZE, 0, 1 }, 33 { -EINVAL, 1, pfn(0), PAGE_SIZE, sgmax + 1, 1 }, 34 { 0, 1, pfn(0), PAGE_SIZE, sgmax, 1 }, 35 { 0, 1, pfn(0), 1, sgmax, 1 }, 36 { 0, 2, pfn(0, 1), 2 * PAGE_SIZE, sgmax, 1 }, 37 { 0, 2, pfn(1, 0), 2 * PAGE_SIZE, sgmax, 2 }, 38 { 0, 3, pfn(0, 1, 2), 3 * PAGE_SIZE, sgmax, 1 }, 39 { 0, 3, pfn(0, 2, 1), 3 * PAGE_SIZE, sgmax, 3 }, 40 { 0, 3, pfn(0, 1, 3), 3 * PAGE_SIZE, sgmax, 2 }, 41 { 0, 3, pfn(1, 2, 4), 3 * PAGE_SIZE, sgmax, 2 }, 42 { 0, 3, pfn(1, 3, 4), 3 * PAGE_SIZE, sgmax, 2 }, 43 { 0, 4, pfn(0, 1, 3, 4), 4 * PAGE_SIZE, sgmax, 2 }, 44 { 0, 5, pfn(0, 1, 3, 4, 5), 5 * PAGE_SIZE, sgmax, 2 }, 45 { 0, 5, pfn(0, 1, 3, 4, 6), 5 * PAGE_SIZE, sgmax, 3 }, 46 { 0, 5, pfn(0, 1, 2, 3, 4), 5 * PAGE_SIZE, sgmax, 1 }, 47 { 0, 5, pfn(0, 1, 2, 3, 4), 5 * PAGE_SIZE, 2 * PAGE_SIZE, 3 }, 48 { 0, 6, pfn(0, 1, 2, 3, 4, 5), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 3 }, 49 { 0, 6, pfn(0, 2, 3, 4, 5, 6), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 4 }, 50 { 0, 6, pfn(0, 1, 3, 4, 5, 6), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 3 }, 51 { 0, 0, NULL, 0, 0, 0 }, 52 }; 53 unsigned int i; 54 55 for (i = 0, test = tests; test->expected_segments; test++, i++) { 56 struct page *pages[MAX_PAGES]; 57 struct sg_table st; 58 int ret; 59 60 set_pages(pages, test->pfn, test->num_pages); 61 62 ret = __sg_alloc_table_from_pages(&st, pages, test->num_pages, 63 0, test->size, test->max_seg, 64 GFP_KERNEL); 65 assert(ret == test->alloc_ret); 66 67 if (test->alloc_ret) 68 continue; 69 70 assert(st.nents == test->expected_segments); 71 assert(st.orig_nents == test->expected_segments); 72 73 sg_free_table(&st); 74 } 75 76 assert(i == (sizeof(tests) / sizeof(tests[0])) - 1); 77 78 return 0; 79 } 80