1221167Sgnn/*-
2221167Sgnn * Copyright(c) 2002-2011 Exar Corp.
3221167Sgnn * All rights reserved.
4221167Sgnn *
5221167Sgnn * Redistribution and use in source and binary forms, with or without
6221167Sgnn * modification are permitted provided the following conditions are met:
7221167Sgnn *
8221167Sgnn *    1. Redistributions of source code must retain the above copyright notice,
9221167Sgnn *       this list of conditions and the following disclaimer.
10221167Sgnn *
11221167Sgnn *    2. Redistributions in binary form must reproduce the above copyright
12221167Sgnn *       notice, this list of conditions and the following disclaimer in the
13221167Sgnn *       documentation and/or other materials provided with the distribution.
14221167Sgnn *
15221167Sgnn *    3. Neither the name of the Exar Corporation nor the names of its
16221167Sgnn *       contributors may be used to endorse or promote products derived from
17221167Sgnn *       this software without specific prior written permission.
18221167Sgnn *
19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29221167Sgnn * POSSIBILITY OF SUCH DAMAGE.
30221167Sgnn */
31221167Sgnn/*$FreeBSD$*/
32221167Sgnn
33221167Sgnn#include <dev/vxge/vxgehal/vxgehal.h>
34221167Sgnn
35221167Sgnn/*
36221167Sgnn * __hal_blockpool_create - Create block pool
37221167Sgnn * @devh: Pointer to HAL Device object.
38221167Sgnn * @blockpool: Block pool to be created.
39221167Sgnn * @pool_size: Number of blocks in the pool.
40221167Sgnn * @pool_incr: Number of blocks to be request from OS at a time
41221167Sgnn * @pool_min: Number of blocks below which new blocks to be requested.
42221167Sgnn * @pool_max: Number of blocks above which block to be freed.
43221167Sgnn *
44221167Sgnn * This function creates block pool
45221167Sgnn */
46221167Sgnn
47221167Sgnnvxge_hal_status_e
48221167Sgnn__hal_blockpool_create(vxge_hal_device_h devh,
49221167Sgnn    __hal_blockpool_t *blockpool,
50221167Sgnn    u32 pool_size,
51221167Sgnn    u32 pool_incr,
52221167Sgnn    u32 pool_min,
53221167Sgnn    u32 pool_max)
54221167Sgnn{
55221167Sgnn	u32 i;
56221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
57221167Sgnn	__hal_blockpool_entry_t *entry;
58221167Sgnn	void *memblock;
59221167Sgnn	dma_addr_t dma_addr;
60221167Sgnn	pci_dma_h dma_handle;
61221167Sgnn	pci_dma_acc_h acc_handle;
62221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
63221167Sgnn
64221167Sgnn	vxge_assert(devh != NULL);
65221167Sgnn	vxge_os_memzero(&dma_handle, sizeof(pci_dma_h));
66221167Sgnn	vxge_os_memzero(&acc_handle, sizeof(pci_dma_acc_h));
67221167Sgnn
68221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
69221167Sgnn	    __FILE__, __func__, __LINE__);
70221167Sgnn
71221167Sgnn	vxge_hal_trace_log_pool("devh = 0x"VXGE_OS_STXFMT", "
72221167Sgnn	    "blockpool = 0x"VXGE_OS_STXFMT", pool_size = %d, pool_incr = %d, "
73221167Sgnn	    "pool_min = %d, pool_max = %d", (ptr_t) devh, (ptr_t) blockpool,
74221167Sgnn	    pool_size, pool_incr, pool_min, pool_max);
75221167Sgnn
76221167Sgnn	if (blockpool == NULL) {
77221167Sgnn		vxge_hal_err_log_pool(
78221167Sgnn		    "%s:%d null pointer passed. blockpool is null",
79221167Sgnn		    __FILE__, __LINE__);
80221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
81221167Sgnn		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
82221167Sgnn		return (VXGE_HAL_FAIL);
83221167Sgnn	}
84221167Sgnn
85221167Sgnn	blockpool->hldev = devh;
86221167Sgnn	blockpool->block_size = VXGE_OS_HOST_PAGE_SIZE;
87221167Sgnn	blockpool->pool_size = 0;
88221167Sgnn	blockpool->pool_incr = pool_incr;
89221167Sgnn	blockpool->pool_min = pool_min;
90221167Sgnn	blockpool->pool_max = pool_max;
91221167Sgnn	blockpool->req_out = 0;
92221167Sgnn
93221167Sgnn#if defined(VXGE_HAL_DMA_CONSISTENT)
94221167Sgnn	blockpool->dma_flags = VXGE_OS_DMA_CONSISTENT;
95221167Sgnn#else
96221167Sgnn	blockpool->dma_flags = VXGE_OS_DMA_STREAMING;
97221167Sgnn#endif
98221167Sgnn
99221167Sgnn	vxge_list_init(&blockpool->free_block_list);
100221167Sgnn
101221167Sgnn	vxge_list_init(&blockpool->free_entry_list);
102221167Sgnn
103221167Sgnn#if defined(VXGE_HAL_BP_POST)
104221167Sgnn	vxge_os_spin_lock_init(&blockpool->pool_lock, hldev->header.pdev);
105221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
106221167Sgnn	vxge_os_spin_lock_init_irq(&blockpool->pool_lock, hldev->header.irqh);
107221167Sgnn#endif
108221167Sgnn
109221167Sgnn	for (i = 0; i < pool_size + pool_max; i++) {
110221167Sgnn
111221167Sgnn		entry = (__hal_blockpool_entry_t *) vxge_os_malloc(
112221167Sgnn		    hldev->header.pdev,
113221167Sgnn		    sizeof(__hal_blockpool_entry_t));
114221167Sgnn		if (entry == NULL) {
115221167Sgnn			__hal_blockpool_destroy(blockpool);
116221167Sgnn
117221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
118221167Sgnn			    __FILE__, __func__, __LINE__,
119221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
120221167Sgnn
121221167Sgnn			return (VXGE_HAL_ERR_OUT_OF_MEMORY);
122221167Sgnn		}
123221167Sgnn
124221167Sgnn		vxge_list_insert(&entry->item, &blockpool->free_entry_list);
125221167Sgnn	}
126221167Sgnn
127221167Sgnn	for (i = 0; i < pool_size; i++) {
128221167Sgnn
129221167Sgnn		memblock = vxge_os_dma_malloc(
130221167Sgnn		    hldev->header.pdev,
131221167Sgnn		    VXGE_OS_HOST_PAGE_SIZE,
132221167Sgnn		    blockpool->dma_flags,
133221167Sgnn		    &dma_handle,
134221167Sgnn		    &acc_handle);
135221167Sgnn
136221167Sgnn		if (memblock == NULL) {
137221167Sgnn			__hal_blockpool_destroy(blockpool);
138221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
139221167Sgnn			    __FILE__, __func__, __LINE__,
140221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
141221167Sgnn
142221167Sgnn			return (VXGE_HAL_ERR_OUT_OF_MEMORY);
143221167Sgnn		}
144221167Sgnn
145221167Sgnn		dma_addr = vxge_os_dma_map(
146221167Sgnn		    hldev->header.pdev,
147221167Sgnn		    dma_handle,
148221167Sgnn		    memblock,
149221167Sgnn		    VXGE_OS_HOST_PAGE_SIZE,
150221167Sgnn		    VXGE_OS_DMA_DIR_BIDIRECTIONAL,
151221167Sgnn		    blockpool->dma_flags);
152221167Sgnn
153221167Sgnn		if (dma_addr == VXGE_OS_INVALID_DMA_ADDR) {
154221167Sgnn			vxge_os_dma_free(hldev->header.pdev,
155221167Sgnn			    memblock,
156221167Sgnn			    VXGE_OS_HOST_PAGE_SIZE,
157221167Sgnn			    blockpool->dma_flags,
158221167Sgnn			    &dma_handle,
159221167Sgnn			    &acc_handle);
160221167Sgnn			__hal_blockpool_destroy(blockpool);
161221167Sgnn
162221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
163221167Sgnn			    __FILE__, __func__, __LINE__,
164221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
165221167Sgnn
166221167Sgnn			return (VXGE_HAL_ERR_OUT_OF_MEMORY);
167221167Sgnn		}
168221167Sgnn
169221167Sgnn		entry = (__hal_blockpool_entry_t *)
170221167Sgnn		    vxge_list_first_get(&blockpool->free_entry_list);
171221167Sgnn
172221167Sgnn		if (entry == NULL) {
173221167Sgnn			entry = (__hal_blockpool_entry_t *) vxge_os_malloc(
174221167Sgnn			    hldev->header.pdev,
175221167Sgnn			    sizeof(__hal_blockpool_entry_t));
176221167Sgnn		}
177221167Sgnn
178221167Sgnn		if (entry != NULL) {
179221167Sgnn			vxge_list_remove(&entry->item);
180221167Sgnn			entry->length = VXGE_OS_HOST_PAGE_SIZE;
181221167Sgnn			entry->memblock = memblock;
182221167Sgnn			entry->dma_addr = dma_addr;
183221167Sgnn			entry->acc_handle = acc_handle;
184221167Sgnn			entry->dma_handle = dma_handle;
185221167Sgnn			vxge_list_insert(&entry->item,
186221167Sgnn			    &blockpool->free_block_list);
187221167Sgnn			blockpool->pool_size++;
188221167Sgnn		} else {
189221167Sgnn			__hal_blockpool_destroy(blockpool);
190221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
191221167Sgnn			    __FILE__, __func__, __LINE__,
192221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
193221167Sgnn
194221167Sgnn			return (VXGE_HAL_ERR_OUT_OF_MEMORY);
195221167Sgnn		}
196221167Sgnn	}
197221167Sgnn
198221167Sgnn	vxge_hal_info_log_pool(
199221167Sgnn	    "Blockpool  block size:%d block pool size: %d",
200221167Sgnn	    blockpool->block_size, blockpool->pool_size);
201221167Sgnn
202221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
203221167Sgnn	    __FILE__, __func__, __LINE__, status);
204221167Sgnn
205221167Sgnn	return (status);
206221167Sgnn}
207221167Sgnn
208221167Sgnn/*
209221167Sgnn * __hal_blockpool_destroy - Deallocates the block pool
210221167Sgnn * @blockpool: blockpool to be deallocated
211221167Sgnn *
212221167Sgnn * This function freeup the memory pool and removes the
213221167Sgnn * block pool.
214221167Sgnn */
215221167Sgnn
216221167Sgnnvoid
217221167Sgnn__hal_blockpool_destroy(
218221167Sgnn    __hal_blockpool_t *blockpool)
219221167Sgnn{
220221167Sgnn	__hal_device_t *hldev;
221221167Sgnn	vxge_list_t *p, *n;
222221167Sgnn
223221167Sgnn	vxge_assert(blockpool != NULL);
224221167Sgnn
225221167Sgnn	hldev = (__hal_device_t *) blockpool->hldev;
226221167Sgnn
227221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
228221167Sgnn	    __FILE__, __func__, __LINE__);
229221167Sgnn
230221167Sgnn	vxge_hal_trace_log_pool("blockpool = 0x"VXGE_OS_STXFMT,
231221167Sgnn	    (ptr_t) blockpool);
232221167Sgnn
233221167Sgnn	if (blockpool == NULL) {
234221167Sgnn		vxge_hal_err_log_pool(
235221167Sgnn		    "%s:%d null pointer passed blockpool = null",
236221167Sgnn		    __FILE__, __LINE__);
237221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 1",
238221167Sgnn		    __FILE__, __func__, __LINE__);
239221167Sgnn		return;
240221167Sgnn	}
241221167Sgnn
242221167Sgnn	vxge_list_for_each_safe(p, n, &blockpool->free_block_list) {
243221167Sgnn
244221167Sgnn		vxge_os_dma_unmap(hldev->header.pdev,
245221167Sgnn		    ((__hal_blockpool_entry_t *) p)->dma_handle,
246221167Sgnn		    ((__hal_blockpool_entry_t *) p)->dma_addr,
247221167Sgnn		    ((__hal_blockpool_entry_t *) p)->length,
248221167Sgnn		    VXGE_OS_DMA_DIR_BIDIRECTIONAL);
249221167Sgnn
250221167Sgnn		vxge_os_dma_free(hldev->header.pdev,
251221167Sgnn		    ((__hal_blockpool_entry_t *) p)->memblock,
252221167Sgnn		    ((__hal_blockpool_entry_t *) p)->length,
253221167Sgnn		    blockpool->dma_flags,
254221167Sgnn		    &((__hal_blockpool_entry_t *) p)->dma_handle,
255221167Sgnn		    &((__hal_blockpool_entry_t *) p)->acc_handle);
256221167Sgnn
257221167Sgnn		vxge_list_remove(&((__hal_blockpool_entry_t *) p)->item);
258221167Sgnn
259221167Sgnn		vxge_os_free(hldev->header.pdev,
260221167Sgnn		    (void *)p, sizeof(__hal_blockpool_entry_t));
261221167Sgnn
262221167Sgnn		blockpool->pool_size--;
263221167Sgnn	}
264221167Sgnn
265221167Sgnn	vxge_list_for_each_safe(p, n, &blockpool->free_entry_list) {
266221167Sgnn
267221167Sgnn		vxge_list_remove(&((__hal_blockpool_entry_t *) p)->item);
268221167Sgnn
269221167Sgnn		vxge_os_free(hldev->header.pdev,
270221167Sgnn		    (void *)p, sizeof(__hal_blockpool_entry_t));
271221167Sgnn
272221167Sgnn	}
273221167Sgnn
274221167Sgnn#if defined(VXGE_HAL_BP_POST)
275221167Sgnn	vxge_os_spin_lock_destroy(&blockpool->pool_lock,
276221167Sgnn	    hldev->header.pdev);
277221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
278221167Sgnn	vxge_os_spin_lock_destroy_irq(&blockpool->pool_lock,
279221167Sgnn	    hldev->header.pdev);
280221167Sgnn#endif
281221167Sgnn
282221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 0",
283221167Sgnn	    __FILE__, __func__, __LINE__);
284221167Sgnn}
285221167Sgnn
286221167Sgnn/*
287221167Sgnn * __hal_blockpool_blocks_add - Request additional blocks
288221167Sgnn * @blockpool: Block pool.
289221167Sgnn *
290221167Sgnn * Requests additional blocks to block pool
291221167Sgnn */
292221167Sgnnstatic inline void
293221167Sgnn__hal_blockpool_blocks_add(
294221167Sgnn    __hal_blockpool_t * blockpool)
295221167Sgnn{
296221167Sgnn	u32 nreq = 0, i;
297221167Sgnn	__hal_device_t *hldev;
298221167Sgnn
299221167Sgnn	vxge_assert(blockpool != NULL);
300221167Sgnn
301221167Sgnn	hldev = (__hal_device_t *) blockpool->hldev;
302221167Sgnn
303221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
304221167Sgnn	    __FILE__, __func__, __LINE__);
305221167Sgnn
306221167Sgnn	vxge_hal_trace_log_pool("blockpool = 0x"VXGE_OS_STXFMT,
307221167Sgnn	    (ptr_t) blockpool);
308221167Sgnn
309221167Sgnn#if defined(VXGE_HAL_BP_POST)
310221167Sgnn	vxge_os_spin_lock(&blockpool->pool_lock);
311221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
312221167Sgnn	vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
313221167Sgnn#endif
314221167Sgnn	if ((blockpool->pool_size + blockpool->req_out) <
315221167Sgnn	    blockpool->pool_min) {
316221167Sgnn		nreq = blockpool->pool_incr;
317221167Sgnn		blockpool->req_out += nreq;
318221167Sgnn	}
319221167Sgnn
320221167Sgnn#if defined(VXGE_HAL_BP_POST)
321221167Sgnn	vxge_os_spin_unlock(&blockpool->pool_lock);
322221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
323221167Sgnn	vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
324221167Sgnn#endif
325221167Sgnn
326221167Sgnn	for (i = 0; i < nreq; i++) {
327221167Sgnn		vxge_os_dma_malloc_async(
328221167Sgnn		    ((__hal_device_t *) blockpool->hldev)->header.pdev,
329221167Sgnn		    blockpool->hldev,
330221167Sgnn		    VXGE_OS_HOST_PAGE_SIZE,
331221167Sgnn		    blockpool->dma_flags);
332221167Sgnn	}
333221167Sgnn
334221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 0",
335221167Sgnn	    __FILE__, __func__, __LINE__);
336221167Sgnn}
337221167Sgnn
338221167Sgnn/*
339221167Sgnn * __hal_blockpool_blocks_remove - Free additional blocks
340221167Sgnn * @blockpool: Block pool.
341221167Sgnn *
342221167Sgnn * Frees additional blocks over maximum from the block pool
343221167Sgnn */
344221167Sgnnstatic inline void
345221167Sgnn__hal_blockpool_blocks_remove(
346221167Sgnn    __hal_blockpool_t * blockpool)
347221167Sgnn{
348221167Sgnn	vxge_list_t *p, *n;
349221167Sgnn	__hal_device_t *hldev;
350221167Sgnn
351221167Sgnn	vxge_assert(blockpool != NULL);
352221167Sgnn
353221167Sgnn	hldev = (__hal_device_t *) blockpool->hldev;
354221167Sgnn
355221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
356221167Sgnn	    __FILE__, __func__, __LINE__);
357221167Sgnn
358221167Sgnn	vxge_hal_trace_log_pool("blockpool = 0x"VXGE_OS_STXFMT,
359221167Sgnn	    (ptr_t) blockpool);
360221167Sgnn
361221167Sgnn#if defined(VXGE_HAL_BP_POST)
362221167Sgnn	vxge_os_spin_lock(&blockpool->pool_lock);
363221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
364221167Sgnn	vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
365221167Sgnn#endif
366221167Sgnn	vxge_list_for_each_safe(p, n, &blockpool->free_block_list) {
367221167Sgnn
368221167Sgnn		if (blockpool->pool_size < blockpool->pool_max)
369221167Sgnn			break;
370221167Sgnn
371221167Sgnn		vxge_os_dma_unmap(
372221167Sgnn		    ((__hal_device_t *) blockpool->hldev)->header.pdev,
373221167Sgnn		    ((__hal_blockpool_entry_t *) p)->dma_handle,
374221167Sgnn		    ((__hal_blockpool_entry_t *) p)->dma_addr,
375221167Sgnn		    ((__hal_blockpool_entry_t *) p)->length,
376221167Sgnn		    VXGE_OS_DMA_DIR_BIDIRECTIONAL);
377221167Sgnn
378221167Sgnn		vxge_os_dma_free(
379221167Sgnn		    ((__hal_device_t *) blockpool->hldev)->header.pdev,
380221167Sgnn		    ((__hal_blockpool_entry_t *) p)->memblock,
381221167Sgnn		    ((__hal_blockpool_entry_t *) p)->length,
382221167Sgnn		    blockpool->dma_flags,
383221167Sgnn		    &((__hal_blockpool_entry_t *) p)->dma_handle,
384221167Sgnn		    &((__hal_blockpool_entry_t *) p)->acc_handle);
385221167Sgnn
386221167Sgnn		vxge_list_remove(&((__hal_blockpool_entry_t *) p)->item);
387221167Sgnn
388221167Sgnn		vxge_list_insert(p, &blockpool->free_entry_list);
389221167Sgnn
390221167Sgnn		blockpool->pool_size--;
391221167Sgnn
392221167Sgnn	}
393221167Sgnn
394221167Sgnn#if defined(VXGE_HAL_BP_POST)
395221167Sgnn	vxge_os_spin_unlock(&blockpool->pool_lock);
396221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
397221167Sgnn	vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
398221167Sgnn#endif
399221167Sgnn
400221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 0",
401221167Sgnn	    __FILE__, __func__, __LINE__);
402221167Sgnn}
403221167Sgnn
404221167Sgnn/*
405221167Sgnn * vxge_hal_blockpool_block_add - callback for vxge_os_dma_malloc_async
406221167Sgnn * @devh: HAL device handle.
407221167Sgnn * @block_addr: Virtual address of the block
408221167Sgnn * @length: Length of the block.
409221167Sgnn * @p_dma_h: Physical address of the block
410221167Sgnn * @acc_handle: DMA acc handle
411221167Sgnn *
412221167Sgnn * Adds a block to block pool
413221167Sgnn */
414221167Sgnnvoid
415221167Sgnnvxge_hal_blockpool_block_add(
416221167Sgnn    vxge_hal_device_h devh,
417221167Sgnn    void *block_addr,
418221167Sgnn    u32 length,
419221167Sgnn    pci_dma_h * dma_h,
420221167Sgnn    pci_dma_acc_h * acc_handle)
421221167Sgnn{
422221167Sgnn	__hal_blockpool_t *blockpool;
423221167Sgnn	__hal_blockpool_entry_t *entry;
424221167Sgnn	__hal_device_t *hldev;
425221167Sgnn	dma_addr_t dma_addr;
426221167Sgnn	vxge_hal_status_e status;
427221167Sgnn	u32 req_out;
428221167Sgnn
429221167Sgnn	vxge_assert(devh != NULL);
430221167Sgnn
431221167Sgnn	hldev = (__hal_device_t *) devh;
432221167Sgnn
433221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
434221167Sgnn	    __FILE__, __func__, __LINE__);
435221167Sgnn
436221167Sgnn	vxge_hal_trace_log_pool("devh = 0x"VXGE_OS_STXFMT", length = %d, "
437221167Sgnn	    "block_addr = 0x"VXGE_OS_STXFMT",  dma_h = 0x"VXGE_OS_STXFMT", "
438221167Sgnn	    "acc_handle = 0x"VXGE_OS_STXFMT, (ptr_t) devh, length,
439221167Sgnn	    (ptr_t) block_addr, (ptr_t) dma_h, (ptr_t) acc_handle);
440221167Sgnn
441221167Sgnn	blockpool = &hldev->block_pool;
442221167Sgnn
443221167Sgnn	if (block_addr == NULL) {
444221167Sgnn#if defined(VXGE_HAL_BP_POST)
445221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
446221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
447221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
448221167Sgnn#endif
449221167Sgnn		blockpool->req_out--;
450221167Sgnn
451221167Sgnn#if defined(VXGE_HAL_BP_POST)
452221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
453221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
454221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
455221167Sgnn#endif
456221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 1",
457221167Sgnn		    __FILE__, __func__, __LINE__);
458221167Sgnn		return;
459221167Sgnn	}
460221167Sgnn
461221167Sgnn	dma_addr = vxge_os_dma_map(hldev->header.pdev,
462221167Sgnn	    *dma_h,
463221167Sgnn	    block_addr,
464221167Sgnn	    length,
465221167Sgnn	    VXGE_OS_DMA_DIR_BIDIRECTIONAL,
466221167Sgnn	    blockpool->dma_flags);
467221167Sgnn
468221167Sgnn	if (dma_addr == VXGE_OS_INVALID_DMA_ADDR) {
469221167Sgnn		vxge_os_dma_free(hldev->header.pdev,
470221167Sgnn		    block_addr,
471221167Sgnn		    length,
472221167Sgnn		    blockpool->dma_flags,
473221167Sgnn		    dma_h,
474221167Sgnn		    acc_handle);
475221167Sgnn#if defined(VXGE_HAL_BP_POST)
476221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
477221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
478221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
479221167Sgnn#endif
480221167Sgnn		blockpool->req_out--;
481221167Sgnn
482221167Sgnn#if defined(VXGE_HAL_BP_POST)
483221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
484221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
485221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
486221167Sgnn#endif
487221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 1",
488221167Sgnn		    __FILE__, __func__, __LINE__);
489221167Sgnn		return;
490221167Sgnn	}
491221167Sgnn
492221167Sgnn#if defined(VXGE_HAL_BP_POST)
493221167Sgnn	vxge_os_spin_lock(&blockpool->pool_lock);
494221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
495221167Sgnn	vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
496221167Sgnn#endif
497221167Sgnn
498221167Sgnn	entry = (__hal_blockpool_entry_t *)
499221167Sgnn	    vxge_list_first_get(&blockpool->free_entry_list);
500221167Sgnn
501221167Sgnn	if (entry == NULL) {
502221167Sgnn		entry = (__hal_blockpool_entry_t *) vxge_os_malloc(
503221167Sgnn		    hldev->header.pdev,
504221167Sgnn		    sizeof(__hal_blockpool_entry_t));
505221167Sgnn	} else {
506221167Sgnn		vxge_list_remove(&entry->item);
507221167Sgnn	}
508221167Sgnn
509221167Sgnn	if (entry != NULL) {
510221167Sgnn		entry->length = length;
511221167Sgnn		entry->memblock = block_addr;
512221167Sgnn		entry->dma_addr = dma_addr;
513221167Sgnn		entry->acc_handle = *acc_handle;
514221167Sgnn		entry->dma_handle = *dma_h;
515221167Sgnn		vxge_list_insert(&entry->item, &blockpool->free_block_list);
516221167Sgnn		blockpool->pool_size++;
517221167Sgnn		status = VXGE_HAL_OK;
518221167Sgnn	} else {
519221167Sgnn		status = VXGE_HAL_ERR_OUT_OF_MEMORY;
520221167Sgnn	}
521221167Sgnn
522221167Sgnn	blockpool->req_out--;
523221167Sgnn
524221167Sgnn	req_out = blockpool->req_out;
525221167Sgnn
526221167Sgnn#if defined(VXGE_HAL_BP_POST)
527221167Sgnn	vxge_os_spin_unlock(&blockpool->pool_lock);
528221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
529221167Sgnn	vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
530221167Sgnn#endif
531221167Sgnn
532221167Sgnn	if (req_out == 0)
533221167Sgnn		__hal_channel_process_pending_list(devh);
534221167Sgnn
535221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
536221167Sgnn	    __FILE__, __func__, __LINE__, status);
537221167Sgnn}
538221167Sgnn
539221167Sgnn/*
540221167Sgnn * __hal_blockpool_malloc - Allocate a memory block from pool
541221167Sgnn * @devh: HAL device handle.
542221167Sgnn * @size: Length of the block.
543221167Sgnn * @dma_addr: Buffer to return DMA Address of the block.
544221167Sgnn * @dma_handle: Buffer to return DMA handle of the block.
545221167Sgnn * @acc_handle: Buffer to return DMA acc handle
546221167Sgnn *
547221167Sgnn *
548221167Sgnn * Allocates a block of memory of given size, either from block pool
549221167Sgnn * or by calling vxge_os_dma_malloc()
550221167Sgnn */
551221167Sgnnvoid *
552221167Sgnn__hal_blockpool_malloc(vxge_hal_device_h devh,
553221167Sgnn    u32 size,
554221167Sgnn    dma_addr_t *dma_addr,
555221167Sgnn    pci_dma_h *dma_handle,
556221167Sgnn    pci_dma_acc_h *acc_handle)
557221167Sgnn{
558221167Sgnn	__hal_blockpool_entry_t *entry;
559221167Sgnn	__hal_blockpool_t *blockpool;
560221167Sgnn	__hal_device_t *hldev;
561221167Sgnn	void *memblock = NULL;
562221167Sgnn
563221167Sgnn	vxge_assert(devh != NULL);
564221167Sgnn
565221167Sgnn	hldev = (__hal_device_t *) devh;
566221167Sgnn
567221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
568221167Sgnn	    __FILE__, __func__, __LINE__);
569221167Sgnn
570221167Sgnn	vxge_hal_trace_log_pool(
571221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", size = %d, "
572221167Sgnn	    "dma_addr = 0x"VXGE_OS_STXFMT", dma_handle = 0x"VXGE_OS_STXFMT", "
573221167Sgnn	    "acc_handle = 0x"VXGE_OS_STXFMT, (ptr_t) devh, size,
574221167Sgnn	    (ptr_t) dma_addr, (ptr_t) dma_handle, (ptr_t) acc_handle);
575221167Sgnn
576221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
577221167Sgnn
578221167Sgnn	if (size != blockpool->block_size) {
579221167Sgnn
580221167Sgnn		memblock = vxge_os_dma_malloc(
581221167Sgnn		    ((__hal_device_t *) devh)->header.pdev,
582221167Sgnn		    size,
583221167Sgnn		    blockpool->dma_flags |
584221167Sgnn		    VXGE_OS_DMA_CACHELINE_ALIGNED,
585221167Sgnn		    dma_handle,
586221167Sgnn		    acc_handle);
587221167Sgnn
588221167Sgnn		if (memblock == NULL) {
589221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
590221167Sgnn			    __FILE__, __func__, __LINE__,
591221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
592221167Sgnn			return (NULL);
593221167Sgnn		}
594221167Sgnn
595221167Sgnn		*dma_addr = vxge_os_dma_map(
596221167Sgnn		    ((__hal_device_t *) devh)->header.pdev,
597221167Sgnn		    *dma_handle,
598221167Sgnn		    memblock,
599221167Sgnn		    size,
600221167Sgnn		    VXGE_OS_DMA_DIR_BIDIRECTIONAL,
601221167Sgnn		    blockpool->dma_flags);
602221167Sgnn
603221167Sgnn		if (*dma_addr == VXGE_OS_INVALID_DMA_ADDR) {
604221167Sgnn			vxge_os_dma_free(((__hal_device_t *) devh)->header.pdev,
605221167Sgnn			    memblock,
606221167Sgnn			    size,
607221167Sgnn			    blockpool->dma_flags |
608221167Sgnn			    VXGE_OS_DMA_CACHELINE_ALIGNED,
609221167Sgnn			    dma_handle,
610221167Sgnn			    acc_handle);
611221167Sgnn
612221167Sgnn			vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
613221167Sgnn			    __FILE__, __func__, __LINE__,
614221167Sgnn			    VXGE_HAL_ERR_OUT_OF_MEMORY);
615221167Sgnn
616221167Sgnn			return (NULL);
617221167Sgnn		}
618221167Sgnn
619221167Sgnn	} else {
620221167Sgnn
621221167Sgnn#if defined(VXGE_HAL_BP_POST)
622221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
623221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
624221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
625221167Sgnn#endif
626221167Sgnn
627221167Sgnn		entry = (__hal_blockpool_entry_t *)
628221167Sgnn		    vxge_list_first_get(&blockpool->free_block_list);
629221167Sgnn
630221167Sgnn		if (entry != NULL) {
631221167Sgnn			vxge_list_remove(&entry->item);
632221167Sgnn			*dma_addr = entry->dma_addr;
633221167Sgnn			*dma_handle = entry->dma_handle;
634221167Sgnn			*acc_handle = entry->acc_handle;
635221167Sgnn			memblock = entry->memblock;
636221167Sgnn
637221167Sgnn			vxge_list_insert(&entry->item,
638221167Sgnn			    &blockpool->free_entry_list);
639221167Sgnn			blockpool->pool_size--;
640221167Sgnn		}
641221167Sgnn
642221167Sgnn#if defined(VXGE_HAL_BP_POST)
643221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
644221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
645221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
646221167Sgnn#endif
647221167Sgnn
648221167Sgnn		if (memblock != NULL)
649221167Sgnn			__hal_blockpool_blocks_add(blockpool);
650221167Sgnn
651221167Sgnn	}
652221167Sgnn
653221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
654221167Sgnn	    __FILE__, __func__, __LINE__, !memblock);
655221167Sgnn
656221167Sgnn	return (memblock);
657221167Sgnn
658221167Sgnn}
659221167Sgnn
660221167Sgnn/*
661221167Sgnn * __hal_blockpool_free - Frees the memory allcoated with __hal_blockpool_malloc
662221167Sgnn * @devh: HAL device handle.
663221167Sgnn * @memblock: Virtual address block
664221167Sgnn * @size: Length of the block.
665221167Sgnn * @dma_addr: DMA Address of the block.
666221167Sgnn * @dma_handle: DMA handle of the block.
667221167Sgnn * @acc_handle: DMA acc handle
668221167Sgnn *
669221167Sgnn *
670221167Sgnn * Frees the memory allocated with __hal_blockpool_malloc to blockpool or system
671221167Sgnn */
672221167Sgnnvoid
673221167Sgnn__hal_blockpool_free(vxge_hal_device_h devh,
674221167Sgnn    void *memblock,
675221167Sgnn    u32 size,
676221167Sgnn    dma_addr_t *dma_addr,
677221167Sgnn    pci_dma_h *dma_handle,
678221167Sgnn    pci_dma_acc_h *acc_handle)
679221167Sgnn{
680221167Sgnn	__hal_blockpool_entry_t *entry;
681221167Sgnn	__hal_blockpool_t *blockpool;
682221167Sgnn	__hal_device_t *hldev;
683221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
684221167Sgnn
685221167Sgnn	vxge_assert(devh != NULL);
686221167Sgnn
687221167Sgnn	hldev = (__hal_device_t *) devh;
688221167Sgnn
689221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
690221167Sgnn	    __FILE__, __func__, __LINE__);
691221167Sgnn
692221167Sgnn	vxge_hal_trace_log_pool("devh = 0x"VXGE_OS_STXFMT", size = %d, "
693221167Sgnn	    "dma_addr = 0x"VXGE_OS_STXFMT", dma_handle = 0x"VXGE_OS_STXFMT", "
694221167Sgnn	    "acc_handle = 0x"VXGE_OS_STXFMT, (ptr_t) devh, size,
695221167Sgnn	    (ptr_t) dma_addr, (ptr_t) dma_handle, (ptr_t) acc_handle);
696221167Sgnn
697221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
698221167Sgnn
699221167Sgnn	if (size != blockpool->block_size) {
700221167Sgnn
701221167Sgnn		vxge_os_dma_unmap(((__hal_device_t *) devh)->header.pdev,
702221167Sgnn		    *dma_handle,
703221167Sgnn		    *dma_addr,
704221167Sgnn		    size,
705221167Sgnn		    VXGE_OS_DMA_DIR_BIDIRECTIONAL);
706221167Sgnn
707221167Sgnn		vxge_os_dma_free(((__hal_device_t *) devh)->header.pdev,
708221167Sgnn		    memblock,
709221167Sgnn		    size,
710221167Sgnn		    blockpool->dma_flags |
711221167Sgnn		    VXGE_OS_DMA_CACHELINE_ALIGNED,
712221167Sgnn		    dma_handle,
713221167Sgnn		    acc_handle);
714221167Sgnn	} else {
715221167Sgnn#if defined(VXGE_HAL_BP_POST)
716221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
717221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
718221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
719221167Sgnn#endif
720221167Sgnn
721221167Sgnn		entry = (__hal_blockpool_entry_t *)
722221167Sgnn		    vxge_list_first_get(&blockpool->free_entry_list);
723221167Sgnn
724221167Sgnn		if (entry == NULL) {
725221167Sgnn			entry = (__hal_blockpool_entry_t *) vxge_os_malloc(
726221167Sgnn			    ((__hal_device_t *) devh)->header.pdev,
727221167Sgnn			    sizeof(__hal_blockpool_entry_t));
728221167Sgnn		} else {
729221167Sgnn			vxge_list_remove(&entry->item);
730221167Sgnn		}
731221167Sgnn
732221167Sgnn		if (entry != NULL) {
733221167Sgnn			entry->length = size;
734221167Sgnn			entry->memblock = memblock;
735221167Sgnn			entry->dma_addr = *dma_addr;
736221167Sgnn			entry->acc_handle = *acc_handle;
737221167Sgnn			entry->dma_handle = *dma_handle;
738221167Sgnn			vxge_list_insert(&entry->item,
739221167Sgnn			    &blockpool->free_block_list);
740221167Sgnn			blockpool->pool_size++;
741221167Sgnn			status = VXGE_HAL_OK;
742221167Sgnn		} else {
743221167Sgnn			status = VXGE_HAL_ERR_OUT_OF_MEMORY;
744221167Sgnn		}
745221167Sgnn
746221167Sgnn#if defined(VXGE_HAL_BP_POST)
747221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
748221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
749221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
750221167Sgnn#endif
751221167Sgnn		if (status == VXGE_HAL_OK)
752221167Sgnn			__hal_blockpool_blocks_remove(blockpool);
753221167Sgnn
754221167Sgnn	}
755221167Sgnn
756221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
757221167Sgnn	    __FILE__, __func__, __LINE__, status);
758221167Sgnn}
759221167Sgnn
760221167Sgnn/*
761221167Sgnn * __hal_blockpool_block_allocate - Allocates a block from block pool
762221167Sgnn * @hldev: Hal device
763221167Sgnn * @size: Size of the block to be allocated
764221167Sgnn *
765221167Sgnn * This function allocates a block from block pool or from the system
766221167Sgnn */
767221167Sgnn__hal_blockpool_entry_t *
768221167Sgnn__hal_blockpool_block_allocate(vxge_hal_device_h devh,
769221167Sgnn    u32 size)
770221167Sgnn{
771221167Sgnn	__hal_blockpool_entry_t *entry = NULL;
772221167Sgnn	__hal_device_t *hldev;
773221167Sgnn	__hal_blockpool_t *blockpool;
774221167Sgnn
775221167Sgnn	vxge_assert(devh != NULL);
776221167Sgnn
777221167Sgnn	hldev = (__hal_device_t *) devh;
778221167Sgnn
779221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
780221167Sgnn	    __FILE__, __func__, __LINE__);
781221167Sgnn
782221167Sgnn	vxge_hal_trace_log_pool("devh = 0x"VXGE_OS_STXFMT", size = %d",
783221167Sgnn	    (ptr_t) devh, size);
784221167Sgnn
785221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
786221167Sgnn
787221167Sgnn	if (size == blockpool->block_size) {
788221167Sgnn#if defined(VXGE_HAL_BP_POST)
789221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
790221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
791221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
792221167Sgnn#endif
793221167Sgnn
794221167Sgnn		entry = (__hal_blockpool_entry_t *)
795221167Sgnn		    vxge_list_first_get(&blockpool->free_block_list);
796221167Sgnn
797221167Sgnn		if (entry != NULL) {
798221167Sgnn			vxge_list_remove(&entry->item);
799221167Sgnn			blockpool->pool_size--;
800221167Sgnn		}
801221167Sgnn
802221167Sgnn#if defined(VXGE_HAL_BP_POST)
803221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
804221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
805221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
806221167Sgnn#endif
807221167Sgnn	}
808221167Sgnn
809221167Sgnn	if (entry != NULL)
810221167Sgnn		__hal_blockpool_blocks_add(blockpool);
811221167Sgnn
812221167Sgnn
813221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
814221167Sgnn	    __FILE__, __func__, __LINE__, !entry);
815221167Sgnn
816221167Sgnn	return (entry);
817221167Sgnn}
818221167Sgnn
819221167Sgnn/*
820221167Sgnn * __hal_blockpool_block_free - Frees a block from block pool
821221167Sgnn * @devh: Hal device
822221167Sgnn * @entry: Entry of block to be freed
823221167Sgnn *
824221167Sgnn * This function frees a block from block pool
825221167Sgnn */
826221167Sgnnvoid
827221167Sgnn__hal_blockpool_block_free(vxge_hal_device_h devh,
828221167Sgnn    __hal_blockpool_entry_t *entry)
829221167Sgnn{
830221167Sgnn	__hal_device_t *hldev;
831221167Sgnn	__hal_blockpool_t *blockpool;
832221167Sgnn
833221167Sgnn	vxge_assert(devh != NULL);
834221167Sgnn
835221167Sgnn	hldev = (__hal_device_t *) devh;
836221167Sgnn
837221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
838221167Sgnn	    __FILE__, __func__, __LINE__);
839221167Sgnn
840221167Sgnn	vxge_hal_trace_log_pool(
841221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", entry = 0x"VXGE_OS_STXFMT,
842221167Sgnn	    (ptr_t) devh, (ptr_t) entry);
843221167Sgnn
844221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
845221167Sgnn
846221167Sgnn	if (entry->length == blockpool->block_size) {
847221167Sgnn#if defined(VXGE_HAL_BP_POST)
848221167Sgnn		vxge_os_spin_lock(&blockpool->pool_lock);
849221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
850221167Sgnn		vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
851221167Sgnn#endif
852221167Sgnn
853221167Sgnn		vxge_list_insert(&entry->item, &blockpool->free_block_list);
854221167Sgnn		blockpool->pool_size++;
855221167Sgnn
856221167Sgnn#if defined(VXGE_HAL_BP_POST)
857221167Sgnn		vxge_os_spin_unlock(&blockpool->pool_lock);
858221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
859221167Sgnn		vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
860221167Sgnn#endif
861221167Sgnn	}
862221167Sgnn
863221167Sgnn	__hal_blockpool_blocks_remove(blockpool);
864221167Sgnn
865221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 0",
866221167Sgnn	    __FILE__, __func__, __LINE__);
867221167Sgnn}
868221167Sgnn
869221167Sgnn
870221167Sgnn/*
871221167Sgnn * __hal_blockpool_list_allocate - Allocate blocks from block pool
872221167Sgnn * @devh: Hal device
873221167Sgnn * @blocklist: List into which the allocated blocks to be inserted
874221167Sgnn * @count: Number of blocks to be allocated
875221167Sgnn *
876221167Sgnn * This function allocates a register from the register pool
877221167Sgnn */
878221167Sgnnvxge_hal_status_e
879221167Sgnn__hal_blockpool_list_allocate(
880221167Sgnn    vxge_hal_device_h devh,
881221167Sgnn    vxge_list_t *blocklist,
882221167Sgnn    u32 count)
883221167Sgnn{
884221167Sgnn	u32 i;
885221167Sgnn	__hal_device_t *hldev;
886221167Sgnn	__hal_blockpool_t *blockpool;
887221167Sgnn	__hal_blockpool_entry_t *block_entry;
888221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
889221167Sgnn
890221167Sgnn	vxge_assert(devh != NULL);
891221167Sgnn
892221167Sgnn	hldev = (__hal_device_t *) devh;
893221167Sgnn
894221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
895221167Sgnn	    __FILE__, __func__, __LINE__);
896221167Sgnn
897221167Sgnn	vxge_hal_trace_log_pool("devh = 0x"VXGE_OS_STXFMT", blocklist = "
898221167Sgnn	    "0x"VXGE_OS_STXFMT", count = %d", (ptr_t) devh,
899221167Sgnn	    (ptr_t) blocklist, count);
900221167Sgnn
901221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
902221167Sgnn
903221167Sgnn	if (blocklist == NULL) {
904221167Sgnn		vxge_hal_err_log_pool(
905221167Sgnn		    "null pointer passed blockpool = 0x"VXGE_OS_STXFMT", "
906221167Sgnn		    "blocklist = 0x"VXGE_OS_STXFMT, (ptr_t) blockpool,
907221167Sgnn		    (ptr_t) blocklist);
908221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 1",
909221167Sgnn		    __FILE__, __func__, __LINE__);
910221167Sgnn		return (VXGE_HAL_FAIL);
911221167Sgnn	}
912221167Sgnn
913221167Sgnn#if defined(VXGE_HAL_BP_POST)
914221167Sgnn	vxge_os_spin_lock(&blockpool->pool_lock);
915221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
916221167Sgnn	vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
917221167Sgnn#endif
918221167Sgnn
919221167Sgnn	vxge_list_init(blocklist);
920221167Sgnn
921221167Sgnn	for (i = 0; i < count; i++) {
922221167Sgnn
923221167Sgnn		block_entry = (__hal_blockpool_entry_t *)
924221167Sgnn		    vxge_list_first_get(&blockpool->free_block_list);
925221167Sgnn
926221167Sgnn		if (block_entry == NULL)
927221167Sgnn			break;
928221167Sgnn
929221167Sgnn		vxge_list_remove(&block_entry->item);
930221167Sgnn
931221167Sgnn		vxge_os_memzero(block_entry->memblock, blockpool->block_size);
932221167Sgnn
933221167Sgnn		vxge_list_insert(&block_entry->item, blocklist);
934221167Sgnn
935221167Sgnn		blockpool->pool_size++;
936221167Sgnn	}
937221167Sgnn
938221167Sgnn#if defined(VXGE_HAL_BP_POST)
939221167Sgnn	vxge_os_spin_unlock(&blockpool->pool_lock);
940221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
941221167Sgnn	vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
942221167Sgnn#endif
943221167Sgnn
944221167Sgnn	if (i < count) {
945221167Sgnn
946221167Sgnn		vxge_hal_err_log_pool("%s:%d Blockpool out of blocks",
947221167Sgnn		    __FILE__, __LINE__);
948221167Sgnn
949221167Sgnn		vxge_assert(FALSE);
950221167Sgnn
951221167Sgnn		__hal_blockpool_list_free(blockpool, blocklist);
952221167Sgnn
953221167Sgnn		status = VXGE_HAL_ERR_OUT_OF_MEMORY;
954221167Sgnn
955221167Sgnn	}
956221167Sgnn
957221167Sgnn	__hal_blockpool_blocks_add(blockpool);
958221167Sgnn
959221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: %d",
960221167Sgnn	    __FILE__, __func__, __LINE__, status);
961221167Sgnn
962221167Sgnn	return (status);
963221167Sgnn}
964221167Sgnn
965221167Sgnn/*
966221167Sgnn * __hal_blockpool_list_free - Free a list of blocks from block pool
967221167Sgnn * @devh: Hal device
968221167Sgnn * @blocklist: List of blocks to be freed
969221167Sgnn *
970221167Sgnn * This function frees a list of blocks to the block pool
971221167Sgnn */
972221167Sgnnvoid
973221167Sgnn__hal_blockpool_list_free(
974221167Sgnn    vxge_hal_device_h devh,
975221167Sgnn    vxge_list_t *blocklist)
976221167Sgnn{
977221167Sgnn	__hal_device_t *hldev;
978221167Sgnn	__hal_blockpool_t *blockpool;
979221167Sgnn	__hal_blockpool_entry_t *block_entry;
980221167Sgnn
981221167Sgnn	vxge_assert(devh != NULL);
982221167Sgnn
983221167Sgnn	hldev = (__hal_device_t *) devh;
984221167Sgnn
985221167Sgnn	vxge_hal_trace_log_pool("==> %s:%s:%d",
986221167Sgnn	    __FILE__, __func__, __LINE__);
987221167Sgnn
988221167Sgnn	vxge_hal_trace_log_pool(
989221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", blocklist = 0x"VXGE_OS_STXFMT,
990221167Sgnn	    (ptr_t) devh, (ptr_t) blocklist);
991221167Sgnn
992221167Sgnn	blockpool = &((__hal_device_t *) devh)->block_pool;
993221167Sgnn
994221167Sgnn	if (blocklist == NULL) {
995221167Sgnn		vxge_hal_err_log_pool(
996221167Sgnn		    "null pointer passed blockpool = 0x"VXGE_OS_STXFMT", "
997221167Sgnn		    "blocklist = 0x"VXGE_OS_STXFMT, (ptr_t) blockpool,
998221167Sgnn		    (ptr_t) blocklist);
999221167Sgnn		vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 1",
1000221167Sgnn		    __FILE__, __func__, __LINE__);
1001221167Sgnn		return;
1002221167Sgnn	}
1003221167Sgnn
1004221167Sgnn#if defined(VXGE_HAL_BP_POST)
1005221167Sgnn	vxge_os_spin_lock(&blockpool->pool_lock);
1006221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
1007221167Sgnn	vxge_os_spin_lock_irq(&blockpool->pool_lock, flags);
1008221167Sgnn#endif
1009221167Sgnn
1010221167Sgnn	while ((block_entry = (__hal_blockpool_entry_t *)
1011221167Sgnn	    vxge_list_first_get(blocklist)) != NULL) {
1012221167Sgnn
1013221167Sgnn		vxge_list_remove(&block_entry->item);
1014221167Sgnn
1015221167Sgnn		vxge_list_insert(&block_entry->item,
1016221167Sgnn		    &blockpool->free_block_list);
1017221167Sgnn
1018221167Sgnn		blockpool->pool_size++;
1019221167Sgnn	}
1020221167Sgnn
1021221167Sgnn#if defined(VXGE_HAL_BP_POST)
1022221167Sgnn	vxge_os_spin_unlock(&blockpool->pool_lock);
1023221167Sgnn#elif defined(VXGE_HAL_BP_POST_IRQ)
1024221167Sgnn	vxge_os_spin_unlock_irq(&blockpool->pool_lock, flags);
1025221167Sgnn#endif
1026221167Sgnn
1027221167Sgnn	__hal_blockpool_blocks_remove(blockpool);
1028221167Sgnn
1029221167Sgnn	vxge_hal_trace_log_pool("<== %s:%s:%d  Result: 0",
1030221167Sgnn	    __FILE__, __func__, __LINE__);
1031221167Sgnn}
1032