diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.c | 34 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_memfree.h | 1 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 46981d48c232..ea45de8c5b8e 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -192,6 +192,40 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o | |||
192 | up(&table->mutex); | 192 | up(&table->mutex); |
193 | } | 193 | } |
194 | 194 | ||
195 | void *mthca_table_find(struct mthca_icm_table *table, int obj) | ||
196 | { | ||
197 | int idx, offset, i; | ||
198 | struct mthca_icm_chunk *chunk; | ||
199 | struct mthca_icm *icm; | ||
200 | struct page *page = NULL; | ||
201 | |||
202 | if (!table->lowmem) | ||
203 | return NULL; | ||
204 | |||
205 | down(&table->mutex); | ||
206 | |||
207 | idx = (obj & (table->num_obj - 1)) * table->obj_size; | ||
208 | icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE]; | ||
209 | offset = idx % MTHCA_TABLE_CHUNK_SIZE; | ||
210 | |||
211 | if (!icm) | ||
212 | goto out; | ||
213 | |||
214 | list_for_each_entry(chunk, &icm->chunk_list, list) { | ||
215 | for (i = 0; i < chunk->npages; ++i) { | ||
216 | if (chunk->mem[i].length >= offset) { | ||
217 | page = chunk->mem[i].page; | ||
218 | break; | ||
219 | } | ||
220 | offset -= chunk->mem[i].length; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | out: | ||
225 | up(&table->mutex); | ||
226 | return page ? lowmem_page_address(page) + offset : NULL; | ||
227 | } | ||
228 | |||
195 | int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, | 229 | int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, |
196 | int start, int end) | 230 | int start, int end) |
197 | { | 231 | { |
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index ef72e430250a..fe7be2a6bc4a 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h | |||
@@ -85,6 +85,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, | |||
85 | void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table); | 85 | void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table); |
86 | int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); | 86 | int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); |
87 | void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); | 87 | void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); |
88 | void *mthca_table_find(struct mthca_icm_table *table, int obj); | ||
88 | int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, | 89 | int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, |
89 | int start, int end); | 90 | int start, int end); |
90 | void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table, | 91 | void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table, |