2 * Copyright(c) 2002-2011 Exar Corp.
5 * Redistribution and use in source and binary forms, with or without
6 * modification are permitted provided the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Exar Corporation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 #include <dev/vxge/vxgehal/vxgehal.h>
37 * vxge_hal_channel_allocate - Allocate memory for channel
38 * @devh: Handle to the device object
39 * @vph: Handle to Virtual Path
40 * @type: Type of channel
41 * @length: Lengths of arrays
42 * @per_dtr_space: ULD requested per dtr space to be allocated in priv
43 * @userdata: User data to be passed back in the callback
45 * This function allocates required memory for the channel and various arrays
49 vxge_hal_channel_allocate(
50 vxge_hal_device_h devh,
52 __hal_channel_type_e type,
57 vxge_hal_device_t *hldev = (vxge_hal_device_t *) devh;
58 __hal_channel_t *channel;
61 vxge_assert((devh != NULL) && (vph != NULL));
63 vxge_hal_trace_log_channel("==> %s:%s:%d",
64 __FILE__, __func__, __LINE__);
66 vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT", vph = "
67 "0x"VXGE_OS_STXFMT", type = %d, length = %d, "
68 "per_dtr_space = %d, userdata = 0x"VXGE_OS_STXFMT,
69 (ptr_t) devh, (ptr_t) vph, type, length, per_dtr_space,
73 case VXGE_HAL_CHANNEL_TYPE_FIFO:
74 size = sizeof(__hal_fifo_t);
76 case VXGE_HAL_CHANNEL_TYPE_RING:
77 size = sizeof(__hal_ring_t);
87 channel = (__hal_channel_t *) vxge_os_malloc(hldev->pdev, size);
88 if (channel == NULL) {
89 vxge_hal_trace_log_channel("<== %s:%s:%d Result: %d",
90 __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
94 vxge_os_memzero(channel, size);
95 vxge_list_init(&channel->item);
97 channel->pdev = hldev->pdev;
102 channel->userdata = userdata;
103 channel->per_dtr_space = per_dtr_space;
105 channel->length = length;
107 channel->dtr_arr = (__hal_dtr_item_t *) vxge_os_malloc(hldev->pdev,
108 sizeof(__hal_dtr_item_t)*length);
109 if (channel->dtr_arr == NULL) {
110 vxge_hal_channel_free(channel);
111 vxge_hal_trace_log_channel("<== %s:%s:%d Result: %d",
112 __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
116 vxge_os_memzero(channel->dtr_arr, sizeof(__hal_dtr_item_t)*length);
118 channel->compl_index = 0;
119 channel->reserve_index = 0;
121 for (i = 0; i < length; i++)
122 channel->dtr_arr[i].state = VXGE_HAL_CHANNEL_DTR_FREE;
124 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
125 __FILE__, __func__, __LINE__);
130 * __hal_channel_free - Free memory allocated for channel
131 * @channel: channel to be freed
133 * This function deallocates memory from the channel and various arrays
137 vxge_hal_channel_free(
138 __hal_channel_t *channel)
141 vxge_hal_device_t *hldev;
143 vxge_assert(channel != NULL);
145 hldev = (vxge_hal_device_t *) channel->devh;
147 vxge_hal_trace_log_channel("==> %s:%s:%d",
148 __FILE__, __func__, __LINE__);
150 vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
153 vxge_assert(channel->pdev);
155 if (channel->dtr_arr) {
156 vxge_os_free(channel->pdev, channel->dtr_arr,
157 sizeof(__hal_dtr_item_t)*channel->length);
158 channel->dtr_arr = NULL;
161 switch (channel->type) {
162 case VXGE_HAL_CHANNEL_TYPE_FIFO:
163 size = sizeof(__hal_fifo_t);
165 case VXGE_HAL_CHANNEL_TYPE_RING:
166 size = sizeof(__hal_ring_t);
172 vxge_os_free(channel->pdev, channel, size);
174 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
175 __FILE__, __func__, __LINE__);
179 * __hal_channel_initialize - Initialize a channel
180 * @channel: channel to be initialized
182 * This function initializes a channel by properly
183 * setting the various references
186 vxge_hal_channel_initialize(
187 __hal_channel_t *channel)
189 vxge_hal_device_t *hldev;
190 __hal_virtualpath_t *vpath;
192 vxge_assert(channel != NULL);
194 hldev = (vxge_hal_device_t *) channel->devh;
195 vpath = (__hal_virtualpath_t *)
196 ((__hal_vpath_handle_t *) channel->vph)->vpath;
198 vxge_assert(vpath != NULL);
200 vxge_hal_trace_log_channel("==> %s:%s:%d",
201 __FILE__, __func__, __LINE__);
203 vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
206 switch (channel->type) {
207 case VXGE_HAL_CHANNEL_TYPE_FIFO:
208 vpath->fifoh = (vxge_hal_fifo_h) channel;
210 &((__hal_fifo_t *) channel)->stats->common_stats;
212 case VXGE_HAL_CHANNEL_TYPE_RING:
213 vpath->ringh = (vxge_hal_ring_h) channel;
215 &((__hal_ring_t *) channel)->stats->common_stats;
223 channel->is_initd = 1;
224 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
225 __FILE__, __func__, __LINE__);
227 return (VXGE_HAL_OK);
231 * __hal_channel_reset - Resets a channel
232 * @channel: channel to be reset
234 * This function resets a channel by properly setting the various references
238 __hal_channel_t *channel)
241 __hal_device_t *hldev;
243 vxge_assert(channel != NULL);
245 hldev = (__hal_device_t *) channel->devh;
247 vxge_hal_trace_log_channel("==> %s:%s:%d",
248 __FILE__, __func__, __LINE__);
250 vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
253 vxge_assert(channel->pdev);
255 channel->compl_index = 0;
256 channel->reserve_index = 0;
258 for (i = 0; i < channel->length; i++) {
259 channel->dtr_arr[i].state =
260 VXGE_HAL_CHANNEL_DTR_FREE;
263 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
264 __FILE__, __func__, __LINE__);
266 return (VXGE_HAL_OK);
270 * vxge_hal_channel_terminate - Deinitializes a channel
271 * @channel: channel to be deinitialized
273 * This function deinitializes a channel by properly
274 * setting the various references
277 vxge_hal_channel_terminate(
278 __hal_channel_t *channel)
280 __hal_device_t *hldev;
281 __hal_virtualpath_t *vpath;
283 vxge_assert(channel != NULL);
285 if (!channel || !channel->is_initd)
288 hldev = (__hal_device_t *) channel->devh;
289 vpath = (__hal_virtualpath_t *)
290 ((__hal_vpath_handle_t *) channel->vph)->vpath;
292 vxge_assert(vpath != NULL);
294 vxge_hal_trace_log_channel("==> %s:%s:%d",
295 __FILE__, __func__, __LINE__);
297 vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
300 switch (channel->type) {
301 case VXGE_HAL_CHANNEL_TYPE_FIFO:
304 case VXGE_HAL_CHANNEL_TYPE_RING:
307 case VXGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
308 vxge_list_remove(&channel->item);
309 vpath->sw_stats->obj_counts.no_sqs--;
311 case VXGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
312 vxge_list_remove(&channel->item);
313 vpath->sw_stats->obj_counts.no_srqs--;
315 case VXGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
316 vxge_list_remove(&channel->item);
317 vpath->sw_stats->obj_counts.no_cqrqs--;
323 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
324 __FILE__, __func__, __LINE__);
328 __hal_channel_init_pending_list(
329 vxge_hal_device_h devh)
331 __hal_device_t *hldev = (__hal_device_t *) devh;
333 vxge_assert(devh != NULL);
335 vxge_hal_trace_log_channel("==> %s:%s:%d",
336 __FILE__, __func__, __LINE__);
338 vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
340 vxge_list_init(&hldev->pending_channel_list);
342 #if defined(VXGE_HAL_VP_CHANNELS)
343 vxge_os_spin_lock_init(&hldev->pending_channel_lock, hldev->pdev);
344 #elif defined(VXGE_HAL_VP_CHANNELS_IRQ)
345 vxge_os_spin_lock_init_irq(&hldev->pending_channel_lock, hldev->irqh);
347 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
348 __FILE__, __func__, __LINE__);
352 __hal_channel_insert_pending_list(
353 __hal_channel_t * channel)
355 __hal_device_t *hldev = (__hal_device_t *) channel->devh;
357 vxge_assert(channel != NULL);
359 vxge_hal_trace_log_channel("==> %s:%s:%d",
360 __FILE__, __func__, __LINE__);
362 vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
365 #if defined(VXGE_HAL_PENDING_CHANNELS)
366 vxge_os_spin_lock(&hldev->pending_channel_lock);
367 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
368 vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
371 vxge_list_insert_before(&channel->item, &hldev->pending_channel_list);
373 #if defined(VXGE_HAL_PENDING_CHANNELS)
374 vxge_os_spin_unlock(&hldev->pending_channel_lock);
375 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
376 vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
379 __hal_channel_process_pending_list(channel->devh);
381 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
382 __FILE__, __func__, __LINE__);
386 __hal_channel_process_pending_list(
387 vxge_hal_device_h devh)
389 vxge_hal_status_e status;
390 __hal_channel_t *channel;
391 __hal_device_t *hldev = (__hal_device_t *) devh;
393 vxge_assert(devh != NULL);
395 vxge_hal_trace_log_channel("==> %s:%s:%d",
396 __FILE__, __func__, __LINE__);
398 vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
402 #if defined(VXGE_HAL_PENDING_CHANNELS)
403 vxge_os_spin_lock(&hldev->pending_channel_lock);
404 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
405 vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
408 channel = (__hal_channel_t *)
409 vxge_list_first_get(&hldev->pending_channel_list);
412 vxge_list_remove(&channel->item);
414 #if defined(VXGE_HAL_PENDING_CHANNELS)
415 vxge_os_spin_unlock(&hldev->pending_channel_lock);
416 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
417 vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
420 if (channel == NULL) {
421 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
422 __FILE__, __func__, __LINE__);
426 switch (channel->type) {
428 status = VXGE_HAL_OK;
432 if (status == VXGE_HAL_ERR_OUT_OF_MEMORY) {
433 #if defined(VXGE_HAL_PENDING_CHANNELS)
434 vxge_os_spin_lock(&hldev->pending_channel_lock);
435 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
436 vxge_os_spin_lock_irq(&hldev->pending_channel_lock,
440 vxge_list_insert(&channel->item,
441 &hldev->pending_channel_list);
443 #if defined(VXGE_HAL_PENDING_CHANNELS)
444 vxge_os_spin_unlock(&hldev->pending_channel_lock);
445 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
446 vxge_os_spin_unlock_irq(&hldev->pending_channel_lock,
449 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
450 __FILE__, __func__, __LINE__);
459 __hal_channel_destroy_pending_list(
460 vxge_hal_device_h devh)
463 __hal_device_t *hldev = (__hal_device_t *) devh;
465 vxge_assert(devh != NULL);
467 vxge_hal_trace_log_channel("==> %s:%s:%d",
468 __FILE__, __func__, __LINE__);
470 vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
473 vxge_list_for_each_safe(p, n, &hldev->pending_channel_list) {
477 switch (((__hal_channel_t *) p)->type) {
484 #if defined(VXGE_HAL_PENDING_CHANNELS)
485 vxge_os_spin_lock_destroy(&hldev->pending_channel_lock,
487 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
488 vxge_os_spin_lock_destroy_irq(&hldev->pending_channel_lock,
491 vxge_hal_trace_log_channel("<== %s:%s:%d Result: 0",
492 __FILE__, __func__, __LINE__);