aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/icm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4/icm.c')
-rw-r--r--drivers/net/mlx4/icm.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 250e24887578..4b3c109d5eae 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -301,9 +301,9 @@ void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
301 mutex_unlock(&table->mutex); 301 mutex_unlock(&table->mutex);
302} 302}
303 303
304void *mlx4_table_find(struct mlx4_icm_table *table, int obj) 304void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle)
305{ 305{
306 int idx, offset, i; 306 int idx, offset, dma_offset, i;
307 struct mlx4_icm_chunk *chunk; 307 struct mlx4_icm_chunk *chunk;
308 struct mlx4_icm *icm; 308 struct mlx4_icm *icm;
309 struct page *page = NULL; 309 struct page *page = NULL;
@@ -313,15 +313,26 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj)
313 313
314 mutex_lock(&table->mutex); 314 mutex_lock(&table->mutex);
315 315
316 idx = obj & (table->num_obj - 1); 316 idx = (obj & (table->num_obj - 1)) * table->obj_size;
317 icm = table->icm[idx / (MLX4_TABLE_CHUNK_SIZE / table->obj_size)]; 317 icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE];
318 offset = idx % (MLX4_TABLE_CHUNK_SIZE / table->obj_size); 318 dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE;
319 319
320 if (!icm) 320 if (!icm)
321 goto out; 321 goto out;
322 322
323 list_for_each_entry(chunk, &icm->chunk_list, list) { 323 list_for_each_entry(chunk, &icm->chunk_list, list) {
324 for (i = 0; i < chunk->npages; ++i) { 324 for (i = 0; i < chunk->npages; ++i) {
325 if (dma_handle && dma_offset >= 0) {
326 if (sg_dma_len(&chunk->mem[i]) > dma_offset)
327 *dma_handle = sg_dma_address(&chunk->mem[i]) +
328 dma_offset;
329 dma_offset -= sg_dma_len(&chunk->mem[i]);
330 }
331 /*
332 * DMA mapping can merge pages but not split them,
333 * so if we found the page, dma_handle has already
334 * been assigned to.
335 */
325 if (chunk->mem[i].length > offset) { 336 if (chunk->mem[i].length > offset) {
326 page = chunk->mem[i].page; 337 page = chunk->mem[i].page;
327 goto out; 338 goto out;