1 /*
2  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
4  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  * $Id$
35  */
36 
37 #include <linux/mm.h>
38 #include <linux/scatterlist.h>
39 #include <linux/sched.h>
40 
41 #include <asm/page.h>
42 
43 #include "mthca_memfree.h"
44 #include "mthca_dev.h"
45 #include "mthca_cmd.h"
46 
47 /*
48  * We allocate in as big chunks as we can, up to a maximum of 256 KB
49  * per chunk.
50  */
51 enum {
52 	MTHCA_ICM_ALLOC_SIZE   = 1 << 18,
53 	MTHCA_TABLE_CHUNK_SIZE = 1 << 18
54 };
55 
56 struct mthca_user_db_table {
57 	struct mutex mutex;
58 	struct {
59 		u64                uvirt;
60 		struct scatterlist mem;
61 		int                refcount;
62 	}                page[0];
63 };
64 
65 static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *chunk)
66 {
67 	int i;
68 
69 	if (chunk->nsg > 0)
70 		pci_unmap_sg(dev->pdev, chunk->mem, chunk->npages,
71 			     PCI_DMA_BIDIRECTIONAL);
72 
73 	for (i = 0; i < chunk->npages; ++i)
74 		__free_pages(chunk->mem[i].page,
75 			     get_order(chunk->mem[i].length));
76 }
77 
78 static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chunk *chunk)
79 {
80 	int i;
81 
82 	for (i = 0; i < chunk->npages; ++i) {
83 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
84 				  lowmem_page_address(chunk->mem[i].page),
85 				  sg_dma_address(&chunk->mem[i]));
86 	}
87 }
88 
89 void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
90 {
91 	struct mthca_icm_chunk *chunk, *tmp;
92 
93 	if (!icm)
94 		return;
95 
96 	list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) {
97 		if (coherent)
98 			mthca_free_icm_coherent(dev, chunk);
99 		else
100 			mthca_free_icm_pages(dev, chunk);
101 
102 		kfree(chunk);
103 	}
104 
105 	kfree(icm);
106 }
107 
108 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
109 {
110 	mem->page = alloc_pages(gfp_mask, order);
111 	if (!mem->page)
112 		return -ENOMEM;
113 
114 	mem->length = PAGE_SIZE << order;
115 	mem->offset = 0;
116 	return 0;
117 }
118 
119 static int mthca_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
120 				    int order, gfp_t gfp_mask)
121 {
122 	void *buf = dma_alloc_coherent(dev, PAGE_SIZE << order, &sg_dma_address(mem),
123 				       gfp_mask);
124 	if (!buf)
125 		return -ENOMEM;
126 
127 	sg_set_buf(mem, buf, PAGE_SIZE << order);
128 	BUG_ON(mem->offset);
129 	sg_dma_len(mem) = PAGE_SIZE << order;
130 	return 0;
131 }
132 
133 struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
134 				  gfp_t gfp_mask, int coherent)
135 {
136 	struct mthca_icm *icm;
137 	struct mthca_icm_chunk *chunk = NULL;
138 	int cur_order;
139 	int ret;
140 
141 	/* We use sg_set_buf for coherent allocs, which assumes low memory */
142 	BUG_ON(coherent && (gfp_mask & __GFP_HIGHMEM));
143 
144 	icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
145 	if (!icm)
146 		return icm;
147 
148 	icm->refcount = 0;
149 	INIT_LIST_HEAD(&icm->chunk_list);
150 
151 	cur_order = get_order(MTHCA_ICM_ALLOC_SIZE);
152 
153 	while (npages > 0) {
154 		if (!chunk) {
155 			chunk = kmalloc(sizeof *chunk,
156 					gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
157 			if (!chunk)
158 				goto fail;
159 
160 			chunk->npages = 0;
161 			chunk->nsg    = 0;
162 			list_add_tail(&chunk->list, &icm->chunk_list);
163 		}
164 
165 		while (1 << cur_order > npages)
166 			--cur_order;
167 
168 		if (coherent)
169 			ret = mthca_alloc_icm_coherent(&dev->pdev->dev,
170 						       &chunk->mem[chunk->npages],
171 						       cur_order, gfp_mask);
172 		else
173 			ret = mthca_alloc_icm_pages(&chunk->mem[chunk->npages],
174 						    cur_order, gfp_mask);
175 
176 		if (!ret) {
177 			++chunk->npages;
178 
179 			if (coherent)
180 				++chunk->nsg;
181 			else if (chunk->npages == MTHCA_ICM_CHUNK_LEN) {
182 				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
183 							chunk->npages,
184 							PCI_DMA_BIDIRECTIONAL);
185 
186 				if (chunk->nsg <= 0)
187 					goto fail;
188 			}
189 
190 			if (chunk->npages == MTHCA_ICM_CHUNK_LEN)
191 				chunk = NULL;
192 
193 			npages -= 1 << cur_order;
194 		} else {
195 			--cur_order;
196 			if (cur_order < 0)
197 				goto fail;
198 		}
199 	}
200 
201 	if (!coherent && chunk) {
202 		chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
203 					chunk->npages,
204 					PCI_DMA_BIDIRECTIONAL);
205 
206 		if (chunk->nsg <= 0)
207 			goto fail;
208 	}
209 
210 	return icm;
211 
212 fail:
213 	mthca_free_icm(dev, icm, coherent);
214 	return NULL;
215 }
216 
217 int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj)
218 {
219 	int i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
220 	int ret = 0;
221 	u8 status;
222 
223 	mutex_lock(&table->mutex);
224 
225 	if (table->icm[i]) {
226 		++table->icm[i]->refcount;
227 		goto out;
228 	}
229 
230 	table->icm[i] = mthca_alloc_icm(dev, MTHCA_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
231 					(table->lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
232 					__GFP_NOWARN, table->coherent);
233 	if (!table->icm[i]) {
234 		ret = -ENOMEM;
235 		goto out;
236 	}
237 
238 	if (mthca_MAP_ICM(dev, table->icm[i], table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
239 			  &status) || status) {
240 		mthca_free_icm(dev, table->icm[i], table->coherent);
241 		table->icm[i] = NULL;
242 		ret = -ENOMEM;
243 		goto out;
244 	}
245 
246 	++table->icm[i]->refcount;
247 
248 out:
249 	mutex_unlock(&table->mutex);
250 	return ret;
251 }
252 
253 void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj)
254 {
255 	int i;
256 	u8 status;
257 
258 	if (!mthca_is_memfree(dev))
259 		return;
260 
261 	i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
262 
263 	mutex_lock(&table->mutex);
264 
265 	if (--table->icm[i]->refcount == 0) {
266 		mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
267 				MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
268 				&status);
269 		mthca_free_icm(dev, table->icm[i], table->coherent);
270 		table->icm[i] = NULL;
271 	}
272 
273 	mutex_unlock(&table->mutex);
274 }
275 
276 void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_handle)
277 {
278 	int idx, offset, dma_offset, i;
279 	struct mthca_icm_chunk *chunk;
280 	struct mthca_icm *icm;
281 	struct page *page = NULL;
282 
283 	if (!table->lowmem)
284 		return NULL;
285 
286 	mutex_lock(&table->mutex);
287 
288 	idx = (obj & (table->num_obj - 1)) * table->obj_size;
289 	icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE];
290 	dma_offset = offset = idx % MTHCA_TABLE_CHUNK_SIZE;
291 
292 	if (!icm)
293 		goto out;
294 
295 	list_for_each_entry(chunk, &icm->chunk_list, list) {
296 		for (i = 0; i < chunk->npages; ++i) {
297 			if (dma_handle && dma_offset >= 0) {
298 				if (sg_dma_len(&chunk->mem[i]) > dma_offset)
299 					*dma_handle = sg_dma_address(&chunk->mem[i]) +
300 						dma_offset;
301 				dma_offset -= sg_dma_len(&chunk->mem[i]);
302 			}
303 			/* DMA mapping can merge pages but not split them,
304 			 * so if we found the page, dma_handle has already
305 			 * been assigned to. */
306 			if (chunk->mem[i].length > offset) {
307 				page = chunk->mem[i].page;
308 				goto out;
309 			}
310 			offset -= chunk->mem[i].length;
311 		}
312 	}
313 
314 out:
315 	mutex_unlock(&table->mutex);
316 	return page ? lowmem_page_address(page) + offset : NULL;
317 }
318 
319 int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
320 			  int start, int end)
321 {
322 	int inc = MTHCA_TABLE_CHUNK_SIZE / table->obj_size;
323 	int i, err;
324 
325 	for (i = start; i <= end; i += inc) {
326 		err = mthca_table_get(dev, table, i);
327 		if (err)
328 			goto fail;
329 	}
330 
331 	return 0;
332 
333 fail:
334 	while (i > start) {
335 		i -= inc;
336 		mthca_table_put(dev, table, i);
337 	}
338 
339 	return err;
340 }
341 
342 void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table,
343 			   int start, int end)
344 {
345 	int i;
346 
347 	if (!mthca_is_memfree(dev))
348 		return;
349 
350 	for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size)
351 		mthca_table_put(dev, table, i);
352 }
353 
354 struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
355 					      u64 virt, int obj_size,
356 					      int nobj, int reserved,
357 					      int use_lowmem, int use_coherent)
358 {
359 	struct mthca_icm_table *table;
360 	int num_icm;
361 	unsigned chunk_size;
362 	int i;
363 	u8 status;
364 
365 	num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
366 
367 	table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
368 	if (!table)
369 		return NULL;
370 
371 	table->virt     = virt;
372 	table->num_icm  = num_icm;
373 	table->num_obj  = nobj;
374 	table->obj_size = obj_size;
375 	table->lowmem   = use_lowmem;
376 	table->coherent = use_coherent;
377 	mutex_init(&table->mutex);
378 
379 	for (i = 0; i < num_icm; ++i)
380 		table->icm[i] = NULL;
381 
382 	for (i = 0; i * MTHCA_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
383 		chunk_size = MTHCA_TABLE_CHUNK_SIZE;
384 		if ((i + 1) * MTHCA_TABLE_CHUNK_SIZE > nobj * obj_size)
385 			chunk_size = nobj * obj_size - i * MTHCA_TABLE_CHUNK_SIZE;
386 
387 		table->icm[i] = mthca_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
388 						(use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
389 						__GFP_NOWARN, use_coherent);
390 		if (!table->icm[i])
391 			goto err;
392 		if (mthca_MAP_ICM(dev, table->icm[i], virt + i * MTHCA_TABLE_CHUNK_SIZE,
393 				  &status) || status) {
394 			mthca_free_icm(dev, table->icm[i], table->coherent);
395 			table->icm[i] = NULL;
396 			goto err;
397 		}
398 
399 		/*
400 		 * Add a reference to this ICM chunk so that it never
401 		 * gets freed (since it contains reserved firmware objects).
402 		 */
403 		++table->icm[i]->refcount;
404 	}
405 
406 	return table;
407 
408 err:
409 	for (i = 0; i < num_icm; ++i)
410 		if (table->icm[i]) {
411 			mthca_UNMAP_ICM(dev, virt + i * MTHCA_TABLE_CHUNK_SIZE,
412 					MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
413 				        &status);
414 			mthca_free_icm(dev, table->icm[i], table->coherent);
415 		}
416 
417 	kfree(table);
418 
419 	return NULL;
420 }
421 
422 void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table)
423 {
424 	int i;
425 	u8 status;
426 
427 	for (i = 0; i < table->num_icm; ++i)
428 		if (table->icm[i]) {
429 			mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
430 					MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
431 					&status);
432 			mthca_free_icm(dev, table->icm[i], table->coherent);
433 		}
434 
435 	kfree(table);
436 }
437 
438 static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int page)
439 {
440 	return dev->uar_table.uarc_base +
441 		uar->index * dev->uar_table.uarc_size +
442 		page * MTHCA_ICM_PAGE_SIZE;
443 }
444 
445 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
446 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
447 {
448 	int ret = 0;
449 	u8 status;
450 	int i;
451 
452 	if (!mthca_is_memfree(dev))
453 		return 0;
454 
455 	if (index < 0 || index > dev->uar_table.uarc_size / 8)
456 		return -EINVAL;
457 
458 	mutex_lock(&db_tab->mutex);
459 
460 	i = index / MTHCA_DB_REC_PER_PAGE;
461 
462 	if ((db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE)       ||
463 	    (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr) ||
464 	    (uaddr & 4095)) {
465 		ret = -EINVAL;
466 		goto out;
467 	}
468 
469 	if (db_tab->page[i].refcount) {
470 		++db_tab->page[i].refcount;
471 		goto out;
472 	}
473 
474 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
475 			     &db_tab->page[i].mem.page, NULL);
476 	if (ret < 0)
477 		goto out;
478 
479 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
480 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
481 
482 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
483 	if (ret < 0) {
484 		put_page(db_tab->page[i].mem.page);
485 		goto out;
486 	}
487 
488 	ret = mthca_MAP_ICM_page(dev, sg_dma_address(&db_tab->page[i].mem),
489 				 mthca_uarc_virt(dev, uar, i), &status);
490 	if (!ret && status)
491 		ret = -EINVAL;
492 	if (ret) {
493 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
494 		put_page(db_tab->page[i].mem.page);
495 		goto out;
496 	}
497 
498 	db_tab->page[i].uvirt    = uaddr;
499 	db_tab->page[i].refcount = 1;
500 
501 out:
502 	mutex_unlock(&db_tab->mutex);
503 	return ret;
504 }
505 
506 void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
507 			 struct mthca_user_db_table *db_tab, int index)
508 {
509 	if (!mthca_is_memfree(dev))
510 		return;
511 
512 	/*
513 	 * To make our bookkeeping simpler, we don't unmap DB
514 	 * pages until we clean up the whole db table.
515 	 */
516 
517 	mutex_lock(&db_tab->mutex);
518 
519 	--db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
520 
521 	mutex_unlock(&db_tab->mutex);
522 }
523 
524 struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
525 {
526 	struct mthca_user_db_table *db_tab;
527 	int npages;
528 	int i;
529 
530 	if (!mthca_is_memfree(dev))
531 		return NULL;
532 
533 	npages = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE;
534 	db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL);
535 	if (!db_tab)
536 		return ERR_PTR(-ENOMEM);
537 
538 	mutex_init(&db_tab->mutex);
539 	for (i = 0; i < npages; ++i) {
540 		db_tab->page[i].refcount = 0;
541 		db_tab->page[i].uvirt    = 0;
542 	}
543 
544 	return db_tab;
545 }
546 
547 void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
548 			       struct mthca_user_db_table *db_tab)
549 {
550 	int i;
551 	u8 status;
552 
553 	if (!mthca_is_memfree(dev))
554 		return;
555 
556 	for (i = 0; i < dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE; ++i) {
557 		if (db_tab->page[i].uvirt) {
558 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
559 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
560 			put_page(db_tab->page[i].mem.page);
561 		}
562 	}
563 
564 	kfree(db_tab);
565 }
566 
567 int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
568 		   u32 qn, __be32 **db)
569 {
570 	int group;
571 	int start, end, dir;
572 	int i, j;
573 	struct mthca_db_page *page;
574 	int ret = 0;
575 	u8 status;
576 
577 	mutex_lock(&dev->db_tab->mutex);
578 
579 	switch (type) {
580 	case MTHCA_DB_TYPE_CQ_ARM:
581 	case MTHCA_DB_TYPE_SQ:
582 		group = 0;
583 		start = 0;
584 		end   = dev->db_tab->max_group1;
585 		dir   = 1;
586 		break;
587 
588 	case MTHCA_DB_TYPE_CQ_SET_CI:
589 	case MTHCA_DB_TYPE_RQ:
590 	case MTHCA_DB_TYPE_SRQ:
591 		group = 1;
592 		start = dev->db_tab->npages - 1;
593 		end   = dev->db_tab->min_group2;
594 		dir   = -1;
595 		break;
596 
597 	default:
598 		ret = -EINVAL;
599 		goto out;
600 	}
601 
602 	for (i = start; i != end; i += dir)
603 		if (dev->db_tab->page[i].db_rec &&
604 		    !bitmap_full(dev->db_tab->page[i].used,
605 				 MTHCA_DB_REC_PER_PAGE)) {
606 			page = dev->db_tab->page + i;
607 			goto found;
608 		}
609 
610 	for (i = start; i != end; i += dir)
611 		if (!dev->db_tab->page[i].db_rec) {
612 			page = dev->db_tab->page + i;
613 			goto alloc;
614 		}
615 
616 	if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
617 		ret = -ENOMEM;
618 		goto out;
619 	}
620 
621 	if (group == 0)
622 		++dev->db_tab->max_group1;
623 	else
624 		--dev->db_tab->min_group2;
625 
626 	page = dev->db_tab->page + end;
627 
628 alloc:
629 	page->db_rec = dma_alloc_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
630 					  &page->mapping, GFP_KERNEL);
631 	if (!page->db_rec) {
632 		ret = -ENOMEM;
633 		goto out;
634 	}
635 	memset(page->db_rec, 0, MTHCA_ICM_PAGE_SIZE);
636 
637 	ret = mthca_MAP_ICM_page(dev, page->mapping,
638 				 mthca_uarc_virt(dev, &dev->driver_uar, i), &status);
639 	if (!ret && status)
640 		ret = -EINVAL;
641 	if (ret) {
642 		dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
643 				  page->db_rec, page->mapping);
644 		goto out;
645 	}
646 
647 	bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
648 
649 found:
650 	j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);
651 	set_bit(j, page->used);
652 
653 	if (group == 1)
654 		j = MTHCA_DB_REC_PER_PAGE - 1 - j;
655 
656 	ret = i * MTHCA_DB_REC_PER_PAGE + j;
657 
658 	page->db_rec[j] = cpu_to_be64((qn << 8) | (type << 5));
659 
660 	*db = (__be32 *) &page->db_rec[j];
661 
662 out:
663 	mutex_unlock(&dev->db_tab->mutex);
664 
665 	return ret;
666 }
667 
668 void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
669 {
670 	int i, j;
671 	struct mthca_db_page *page;
672 	u8 status;
673 
674 	i = db_index / MTHCA_DB_REC_PER_PAGE;
675 	j = db_index % MTHCA_DB_REC_PER_PAGE;
676 
677 	page = dev->db_tab->page + i;
678 
679 	mutex_lock(&dev->db_tab->mutex);
680 
681 	page->db_rec[j] = 0;
682 	if (i >= dev->db_tab->min_group2)
683 		j = MTHCA_DB_REC_PER_PAGE - 1 - j;
684 	clear_bit(j, page->used);
685 
686 	if (bitmap_empty(page->used, MTHCA_DB_REC_PER_PAGE) &&
687 	    i >= dev->db_tab->max_group1 - 1) {
688 		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
689 
690 		dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
691 				  page->db_rec, page->mapping);
692 		page->db_rec = NULL;
693 
694 		if (i == dev->db_tab->max_group1) {
695 			--dev->db_tab->max_group1;
696 			/* XXX may be able to unmap more pages now */
697 		}
698 		if (i == dev->db_tab->min_group2)
699 			++dev->db_tab->min_group2;
700 	}
701 
702 	mutex_unlock(&dev->db_tab->mutex);
703 }
704 
705 int mthca_init_db_tab(struct mthca_dev *dev)
706 {
707 	int i;
708 
709 	if (!mthca_is_memfree(dev))
710 		return 0;
711 
712 	dev->db_tab = kmalloc(sizeof *dev->db_tab, GFP_KERNEL);
713 	if (!dev->db_tab)
714 		return -ENOMEM;
715 
716 	mutex_init(&dev->db_tab->mutex);
717 
718 	dev->db_tab->npages     = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE;
719 	dev->db_tab->max_group1 = 0;
720 	dev->db_tab->min_group2 = dev->db_tab->npages - 1;
721 
722 	dev->db_tab->page = kmalloc(dev->db_tab->npages *
723 				    sizeof *dev->db_tab->page,
724 				    GFP_KERNEL);
725 	if (!dev->db_tab->page) {
726 		kfree(dev->db_tab);
727 		return -ENOMEM;
728 	}
729 
730 	for (i = 0; i < dev->db_tab->npages; ++i)
731 		dev->db_tab->page[i].db_rec = NULL;
732 
733 	return 0;
734 }
735 
736 void mthca_cleanup_db_tab(struct mthca_dev *dev)
737 {
738 	int i;
739 	u8 status;
740 
741 	if (!mthca_is_memfree(dev))
742 		return;
743 
744 	/*
745 	 * Because we don't always free our UARC pages when they
746 	 * become empty to make mthca_free_db() simpler we need to
747 	 * make a sweep through the doorbell pages and free any
748 	 * leftover pages now.
749 	 */
750 	for (i = 0; i < dev->db_tab->npages; ++i) {
751 		if (!dev->db_tab->page[i].db_rec)
752 			continue;
753 
754 		if (!bitmap_empty(dev->db_tab->page[i].used, MTHCA_DB_REC_PER_PAGE))
755 			mthca_warn(dev, "Kernel UARC page %d not empty\n", i);
756 
757 		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
758 
759 		dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
760 				  dev->db_tab->page[i].db_rec,
761 				  dev->db_tab->page[i].mapping);
762 	}
763 
764 	kfree(dev->db_tab->page);
765 	kfree(dev->db_tab);
766 }
767