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#ifndef VXGE_QUEUE_H 34221167Sgnn#define VXGE_QUEUE_H 35221167Sgnn 36221167Sgnn__EXTERN_BEGIN_DECLS 37221167Sgnn 38221167Sgnn#define VXGE_QUEUE_BUF_SIZE 0x1000 39221167Sgnn#define VXGE_DEFAULT_EVENT_MAX_DATA_SIZE 16 40221167Sgnn 41221167Sgnn/* 42221167Sgnn * enum vxge_queue_status_e - Enumerates return codes of the vxge_queue 43221167Sgnn * manipulation APIs. 44221167Sgnn * @VXGE_QUEUE_IS_FULL: Queue is full, need to grow. 45221167Sgnn * @VXGE_QUEUE_IS_EMPTY: Queue is empty. 46221167Sgnn * @VXGE_QUEUE_OUT_OF_MEMORY: Out of memory. 47221167Sgnn * @VXGE_QUEUE_NOT_ENOUGH_SPACE: Exceeded specified event size, 48221167Sgnn * see vxge_queue_consume(). 49221167Sgnn * @VXGE_QUEUE_OK: Neither one of the codes listed above. 50221167Sgnn * 51221167Sgnn * Enumerates return codes of vxge_queue_consume() 52221167Sgnn * and vxge_queue_produce() APIs. 53221167Sgnn */ 54221167Sgnntypedef enum vxge_queue_status_e { 55221167Sgnn VXGE_QUEUE_OK = 0, 56221167Sgnn VXGE_QUEUE_IS_FULL = 1, 57221167Sgnn VXGE_QUEUE_IS_EMPTY = 2, 58221167Sgnn VXGE_QUEUE_OUT_OF_MEMORY = 3, 59221167Sgnn VXGE_QUEUE_NOT_ENOUGH_SPACE = 4 60221167Sgnn} vxge_queue_status_e; 61221167Sgnn 62221167Sgnntypedef void *vxge_queue_h; 63221167Sgnn 64221167Sgnn/* 65221167Sgnn * struct vxge_queue_item_t - Queue item. 66221167Sgnn * @item: List item. Note that the queue is "built" on top of 67221167Sgnn * the bi-directional linked list. 68221167Sgnn * @event_type: Event type. Includes (but is not restricted to) 69221167Sgnn * one of the vxge_hal_event_e {} enumerated types. 70221167Sgnn * @data_size: Size of the enqueued user data. Note that vxge_queue_t 71221167Sgnn * items are allowed to have variable sizes. 72221167Sgnn * @is_critical: For critical events, e.g. ECC. 73221167Sgnn * @context: Opaque (void *) "context", for instance event producer object. 74221167Sgnn * 75221167Sgnn * Item of the vxge_queue_t {}. The queue is protected 76221167Sgnn * in terms of multi-threaded concurrent access. 77221167Sgnn * See also: vxge_queue_t {}. 78221167Sgnn */ 79221167Sgnntypedef struct vxge_queue_item_t { 80221167Sgnn vxge_list_t item; 81221167Sgnn vxge_hal_event_e event_type; 82221167Sgnn u32 data_size; 83221167Sgnn u32 is_critical; 84221167Sgnn void *context; 85221167Sgnn} vxge_queue_item_t; 86221167Sgnn 87221167Sgnn/* 88221167Sgnn * function vxge_queued_f - Item-enqueued callback. 89221167Sgnn * @data: Per-queue context independent of the event. E.g., device handle. 90221167Sgnn * @event_type: HAL or ULD-defined event type. Note that HAL own 91221167Sgnn * events are enumerated by vxge_hal_event_e {}. 92221167Sgnn * 93221167Sgnn * Per-queue optional callback. If not NULL, called by HAL each 94221167Sgnn * time an event gets added to the queue. 95221167Sgnn */ 96221167Sgnntypedef void (*vxge_queued_f) (void *data, u32 event_type); 97221167Sgnn 98221167Sgnn/* 99221167Sgnn * struct vxge_queue_t - Protected dynamic queue of variable-size items. 100221167Sgnn * @start_ptr: Points to the start of the queue. 101221167Sgnn * @end_ptr: Points to the end of the queue. 102221167Sgnn * @head_ptr: Points to the head of the queue. It gets changed during queue 103221167Sgnn * produce/consume operations. 104221167Sgnn * @tail_ptr: Points to the tail of the queue. It gets changed during queue 105221167Sgnn * produce/consume operations. 106221167Sgnn * @lock: Lock for queue operations(syncronization purpose). 107221167Sgnn * @pages_initial:Number of pages to be initially allocated at the time 108221167Sgnn * of queue creation. 109221167Sgnn * @pages_max: Max number of pages that can be allocated in the queue. 110221167Sgnn * @pages_current: Number of pages currently allocated 111221167Sgnn * @list_head: Points to the list of queue elements that are produced, but yet 112221167Sgnn * to be consumed. 113221167Sgnn * @hldev: HAL device handle 114221167Sgnn * @pdev: PCI device handle 115221167Sgnn * @irqh: PCI device IRQ handle. 116221167Sgnn * @queued_func: Optional callback function to be called each time a new 117221167Sgnn * item is added to the queue. 118221167Sgnn * @queued_data: Arguments to the callback function. 119221167Sgnn * @has_critical_event: Non-zero, if the queue contains a critical event, 120221167Sgnn * see vxge_hal_event_e {}. 121221167Sgnn * Protected dynamically growing queue. The queue is used to support multiple 122221167Sgnn * producer/consumer type scenarios. The queue is a strict FIFO: first come 123221167Sgnn * first served. 124221167Sgnn * Queue users may "produce" (see vxge_queue_produce()) and "consume" 125221167Sgnn * (see vxge_queue_consume()) items (a.k.a. events) variable sizes. 126221167Sgnn * See also: vxge_queue_item_t {}. 127221167Sgnn */ 128221167Sgnntypedef struct vxge_queue_t { 129221167Sgnn void *start_ptr; 130221167Sgnn void *end_ptr; 131221167Sgnn void *head_ptr; 132221167Sgnn void *tail_ptr; 133221167Sgnn spinlock_t lock; 134221167Sgnn u32 pages_initial; 135221167Sgnn u32 pages_max; 136221167Sgnn u32 pages_current; 137221167Sgnn vxge_list_t list_head; 138221167Sgnn vxge_hal_device_h hldev; 139221167Sgnn pci_dev_h pdev; 140221167Sgnn pci_irq_h irqh; 141221167Sgnn vxge_queued_f queued_func; 142221167Sgnn void *queued_data; 143221167Sgnn u32 has_critical_event; 144221167Sgnn} vxge_queue_t; 145221167Sgnn 146221167Sgnn/* ========================== PUBLIC API ================================= */ 147221167Sgnn 148221167Sgnn/* 149221167Sgnn * vxge_queue_create - Create protected first-in-first-out queue. 150221167Sgnn * @devh: HAL device handle. 151221167Sgnn * @pages_initial: Number of pages to be initially allocated at the 152221167Sgnn * time of queue creation. 153221167Sgnn * @pages_max: Max number of pages that can be allocated in the queue. 154221167Sgnn * @queued_func: Optional callback function to be called each time a new item is 155221167Sgnn * added to the queue. 156221167Sgnn * @queued_data: Argument to the callback function. 157221167Sgnn * 158221167Sgnn * Create protected (fifo) queue. 159221167Sgnn * 160221167Sgnn * Returns: Pointer to vxge_queue_t structure, 161221167Sgnn * NULL - on failure. 162221167Sgnn * 163221167Sgnn * See also: vxge_queue_item_t {}, vxge_queue_destroy(). 164221167Sgnn */ 165221167Sgnnvxge_queue_h 166221167Sgnnvxge_queue_create(vxge_hal_device_h devh, 167221167Sgnn u32 pages_initial, 168221167Sgnn u32 pages_max, 169221167Sgnn vxge_queued_f queued_func, 170221167Sgnn void *queued_data); 171221167Sgnn 172221167Sgnn/* 173221167Sgnn * vxge_queue_destroy - Destroy vxge_queue_t object. 174221167Sgnn * @queueh: Queue handle. 175221167Sgnn * 176221167Sgnn * Destroy the specified vxge_queue_t object. 177221167Sgnn * 178221167Sgnn * See also: vxge_queue_item_t {}, vxge_queue_create(). 179221167Sgnn */ 180221167Sgnnvoid 181221167Sgnnvxge_queue_destroy(vxge_queue_h queueh); 182221167Sgnn 183221167Sgnn/* 184221167Sgnn * vxge_queue_item_data - Get item's data. 185221167Sgnn * @item: Queue item. 186221167Sgnn * 187221167Sgnn * Returns: item data(variable size). Note that vxge_queue_t 188221167Sgnn * contains items comprized of a fixed vxge_queue_item_t "header" 189221167Sgnn * and a variable size data. This function returns the variable 190221167Sgnn * user-defined portion of the queue item. 191221167Sgnn */ 192221167Sgnnvoid * 193221167Sgnnvxge_queue_item_data(vxge_queue_item_t *item); 194221167Sgnn 195221167Sgnn/* 196221167Sgnn * vxge_queue_produce - Enqueue an item (see vxge_queue_item_t {}) 197221167Sgnn * into the specified queue. 198221167Sgnn * @queueh: Queue handle. 199221167Sgnn * @event_type: Event type. One of the enumerated event types 200221167Sgnn * that both consumer and producer "understand". 201221167Sgnn * For an example, please refer to vxge_hal_event_e. 202221167Sgnn * @context: Opaque (void *) "context", for instance event producer object. 203221167Sgnn * @is_critical: For critical event, e.g. ECC. 204221167Sgnn * @data_size: Size of the @data. 205221167Sgnn * @data: User data of variable @data_size that is _copied_ into 206221167Sgnn * the new queue item (see vxge_queue_item_t {}). Upon return 207221167Sgnn * from the call the @data memory can be re-used or released. 208221167Sgnn * 209221167Sgnn * Enqueue a new item. 210221167Sgnn * 211221167Sgnn * Returns: VXGE_QUEUE_OK - success. 212221167Sgnn * VXGE_QUEUE_IS_FULL - Queue is full. 213221167Sgnn * VXGE_QUEUE_OUT_OF_MEMORY - Memory allocation failed. 214221167Sgnn * 215221167Sgnn * See also: vxge_queue_item_t {}, vxge_queue_consume(). 216221167Sgnn */ 217221167Sgnnvxge_queue_status_e 218221167Sgnnvxge_queue_produce(vxge_queue_h queueh, 219221167Sgnn u32 event_type, 220221167Sgnn void *context, 221221167Sgnn u32 is_critical, 222221167Sgnn const u32 data_size, 223221167Sgnn void *data); 224221167Sgnn 225221167Sgnn/* 226221167Sgnn * vxge_queue_produce_context - Enqueue context. 227221167Sgnn * @queueh: Queue handle. 228221167Sgnn * @event_type: Event type. One of the enumerated event types 229221167Sgnn * that both consumer and producer "understand". 230221167Sgnn * For an example, please refer to vxge_hal_event_e. 231221167Sgnn * @context: Opaque (void *) "context", for instance event producer object. 232221167Sgnn * 233221167Sgnn * Enqueue Context. 234221167Sgnn * 235221167Sgnn * Returns: VXGE_QUEUE_OK - success. 236221167Sgnn * VXGE_QUEUE_IS_EMPTY - Queue is empty. 237221167Sgnn * VXGE_QUEUE_NOT_ENOUGH_SPACE - Requested item size(@data_max_size) 238221167Sgnn * is too small to accomodate an item from the queue. 239221167Sgnn * 240221167Sgnn * See also: vxge_queue_item_t {}, vxge_queue_produce(). 241221167Sgnn */ 242221167Sgnnstatic inline vxge_queue_status_e 243221167Sgnn/* LINTED */ 244221167Sgnnvxge_queue_produce_context(vxge_queue_h queueh, 245221167Sgnn u32 event_type, 246221167Sgnn void *context) 247221167Sgnn{ 248221167Sgnn return (vxge_queue_produce(queueh, event_type, context, 0, 0, 0)); 249221167Sgnn} 250221167Sgnn 251221167Sgnn/* 252221167Sgnn * vxge_queue_consume - Dequeue an item from the specified queue. 253221167Sgnn * @queueh: Queue handle. 254221167Sgnn * @data_max_size: Maximum expected size of the item. 255221167Sgnn * @item: Memory area into which the item is _copied_ upon return 256221167Sgnn * from the function. 257221167Sgnn * 258221167Sgnn * Dequeue an item from the queue. The caller is required to provide 259221167Sgnn * enough space for the item. 260221167Sgnn * 261221167Sgnn * Returns: VXGE_QUEUE_OK - success. 262221167Sgnn * VXGE_QUEUE_IS_EMPTY - Queue is empty. 263221167Sgnn * VXGE_QUEUE_NOT_ENOUGH_SPACE - Requested item size(@data_max_size) 264221167Sgnn * is too small to accomodate an item from the queue. 265221167Sgnn * 266221167Sgnn * See also: vxge_queue_item_t {}, vxge_queue_produce(). 267221167Sgnn */ 268221167Sgnnvxge_queue_status_e 269221167Sgnnvxge_queue_consume(vxge_queue_h queueh, 270221167Sgnn u32 data_max_size, 271221167Sgnn vxge_queue_item_t *item); 272221167Sgnn 273221167Sgnn/* 274221167Sgnn * vxge_queue_flush - Flush, or empty, the queue. 275221167Sgnn * @queueh: Queue handle. 276221167Sgnn * 277221167Sgnn * Flush the queue, i.e. make it empty by consuming all events 278221167Sgnn * without invoking the event processing logic (callbacks, etc.) 279221167Sgnn */ 280221167Sgnnvoid 281221167Sgnnvxge_queue_flush(vxge_queue_h queueh); 282221167Sgnn 283221167Sgnn/* 284221167Sgnn * vxge_io_queue_grow - Dynamically increases the size of the queue. 285221167Sgnn * @queueh: Queue handle. 286221167Sgnn * 287221167Sgnn * This function is called in the case of no slot avaialble in the queue 288221167Sgnn * to accomodate the newly received event. 289221167Sgnn * Note that queue cannot grow beyond the max size specified for the 290221167Sgnn * queue. 291221167Sgnn * 292221167Sgnn * Returns VXGE_QUEUE_OK: On success. 293221167Sgnn * VXGE_QUEUE_OUT_OF_MEMORY : No memory is available. 294221167Sgnn */ 295221167Sgnnvxge_queue_status_e 296221167Sgnnvxge_io_queue_grow(vxge_queue_h qh); 297221167Sgnn 298221167Sgnn/* 299221167Sgnn * vxge_queue_get_reset_critical - Check for critical events in the queue, 300221167Sgnn * @queueh: Queue handle. 301221167Sgnn * 302221167Sgnn * Check for critical event(s) in the queue, and reset the 303221167Sgnn * "has-critical-event" flag upon return. 304221167Sgnn * Returns: 1 - if the queue contains atleast one critical event. 305221167Sgnn * 0 - If there are no critical events in the queue. 306221167Sgnn */ 307221167Sgnnu32 308221167Sgnnvxge_queue_get_reset_critical(vxge_queue_h queueh); 309221167Sgnn 310221167Sgnn__EXTERN_END_DECLS 311221167Sgnn 312221167Sgnn#endif /* VXGE_QUEUE_H */ 313