diff options
Diffstat (limited to 'lib/sg_pool.c')
-rw-r--r-- | lib/sg_pool.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/sg_pool.c b/lib/sg_pool.c index cff20df2695e..db29e5c1f790 100644 --- a/lib/sg_pool.c +++ b/lib/sg_pool.c | |||
@@ -70,18 +70,27 @@ static struct scatterlist *sg_pool_alloc(unsigned int nents, gfp_t gfp_mask) | |||
70 | /** | 70 | /** |
71 | * sg_free_table_chained - Free a previously mapped sg table | 71 | * sg_free_table_chained - Free a previously mapped sg table |
72 | * @table: The sg table header to use | 72 | * @table: The sg table header to use |
73 | * @first_chunk: was first_chunk not NULL in sg_alloc_table_chained? | 73 | * @nents_first_chunk: size of the first_chunk SGL passed to |
74 | * sg_alloc_table_chained | ||
74 | * | 75 | * |
75 | * Description: | 76 | * Description: |
76 | * Free an sg table previously allocated and setup with | 77 | * Free an sg table previously allocated and setup with |
77 | * sg_alloc_table_chained(). | 78 | * sg_alloc_table_chained(). |
78 | * | 79 | * |
80 | * @nents_first_chunk has to be same with that same parameter passed | ||
81 | * to sg_alloc_table_chained(). | ||
82 | * | ||
79 | **/ | 83 | **/ |
80 | void sg_free_table_chained(struct sg_table *table, bool first_chunk) | 84 | void sg_free_table_chained(struct sg_table *table, |
85 | unsigned nents_first_chunk) | ||
81 | { | 86 | { |
82 | if (first_chunk && table->orig_nents <= SG_CHUNK_SIZE) | 87 | if (table->orig_nents <= nents_first_chunk) |
83 | return; | 88 | return; |
84 | __sg_free_table(table, SG_CHUNK_SIZE, first_chunk, sg_pool_free); | 89 | |
90 | if (nents_first_chunk == 1) | ||
91 | nents_first_chunk = 0; | ||
92 | |||
93 | __sg_free_table(table, SG_CHUNK_SIZE, nents_first_chunk, sg_pool_free); | ||
85 | } | 94 | } |
86 | EXPORT_SYMBOL_GPL(sg_free_table_chained); | 95 | EXPORT_SYMBOL_GPL(sg_free_table_chained); |
87 | 96 | ||
@@ -90,31 +99,41 @@ EXPORT_SYMBOL_GPL(sg_free_table_chained); | |||
90 | * @table: The sg table header to use | 99 | * @table: The sg table header to use |
91 | * @nents: Number of entries in sg list | 100 | * @nents: Number of entries in sg list |
92 | * @first_chunk: first SGL | 101 | * @first_chunk: first SGL |
102 | * @nents_first_chunk: number of the SGL of @first_chunk | ||
93 | * | 103 | * |
94 | * Description: | 104 | * Description: |
95 | * Allocate and chain SGLs in an sg table. If @nents@ is larger than | 105 | * Allocate and chain SGLs in an sg table. If @nents@ is larger than |
96 | * SG_CHUNK_SIZE a chained sg table will be setup. | 106 | * @nents_first_chunk a chained sg table will be setup. @first_chunk is |
107 | * ignored if nents_first_chunk <= 1 because user expects the SGL points | ||
108 | * non-chain SGL. | ||
97 | * | 109 | * |
98 | **/ | 110 | **/ |
99 | int sg_alloc_table_chained(struct sg_table *table, int nents, | 111 | int sg_alloc_table_chained(struct sg_table *table, int nents, |
100 | struct scatterlist *first_chunk) | 112 | struct scatterlist *first_chunk, unsigned nents_first_chunk) |
101 | { | 113 | { |
102 | int ret; | 114 | int ret; |
103 | 115 | ||
104 | BUG_ON(!nents); | 116 | BUG_ON(!nents); |
105 | 117 | ||
106 | if (first_chunk) { | 118 | if (first_chunk && nents_first_chunk) { |
107 | if (nents <= SG_CHUNK_SIZE) { | 119 | if (nents <= nents_first_chunk) { |
108 | table->nents = table->orig_nents = nents; | 120 | table->nents = table->orig_nents = nents; |
109 | sg_init_table(table->sgl, nents); | 121 | sg_init_table(table->sgl, nents); |
110 | return 0; | 122 | return 0; |
111 | } | 123 | } |
112 | } | 124 | } |
113 | 125 | ||
126 | /* User supposes that the 1st SGL includes real entry */ | ||
127 | if (nents_first_chunk <= 1) { | ||
128 | first_chunk = NULL; | ||
129 | nents_first_chunk = 0; | ||
130 | } | ||
131 | |||
114 | ret = __sg_alloc_table(table, nents, SG_CHUNK_SIZE, | 132 | ret = __sg_alloc_table(table, nents, SG_CHUNK_SIZE, |
115 | first_chunk, GFP_ATOMIC, sg_pool_alloc); | 133 | first_chunk, nents_first_chunk, |
134 | GFP_ATOMIC, sg_pool_alloc); | ||
116 | if (unlikely(ret)) | 135 | if (unlikely(ret)) |
117 | sg_free_table_chained(table, (bool)first_chunk); | 136 | sg_free_table_chained(table, nents_first_chunk); |
118 | return ret; | 137 | return ret; |
119 | } | 138 | } |
120 | EXPORT_SYMBOL_GPL(sg_alloc_table_chained); | 139 | EXPORT_SYMBOL_GPL(sg_alloc_table_chained); |