1/*- 2 * Copyright(c) 2002-2011 Exar Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification are permitted provided the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 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. 14 * 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. 18 * 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. 30 */ 31/*$FreeBSD$*/ 32 33#ifndef VXGE_QUEUE_H 34#define VXGE_QUEUE_H 35 36__EXTERN_BEGIN_DECLS 37 38#define VXGE_QUEUE_BUF_SIZE 0x1000 39#define VXGE_DEFAULT_EVENT_MAX_DATA_SIZE 16 40 41/* 42 * enum vxge_queue_status_e - Enumerates return codes of the vxge_queue 43 * manipulation APIs. 44 * @VXGE_QUEUE_IS_FULL: Queue is full, need to grow. 45 * @VXGE_QUEUE_IS_EMPTY: Queue is empty. 46 * @VXGE_QUEUE_OUT_OF_MEMORY: Out of memory. 47 * @VXGE_QUEUE_NOT_ENOUGH_SPACE: Exceeded specified event size, 48 * see vxge_queue_consume(). 49 * @VXGE_QUEUE_OK: Neither one of the codes listed above. 50 * 51 * Enumerates return codes of vxge_queue_consume() 52 * and vxge_queue_produce() APIs. 53 */ 54typedef enum vxge_queue_status_e { 55 VXGE_QUEUE_OK = 0, 56 VXGE_QUEUE_IS_FULL = 1, 57 VXGE_QUEUE_IS_EMPTY = 2, 58 VXGE_QUEUE_OUT_OF_MEMORY = 3, 59 VXGE_QUEUE_NOT_ENOUGH_SPACE = 4 60} vxge_queue_status_e; 61 62typedef void *vxge_queue_h; 63 64/* 65 * struct vxge_queue_item_t - Queue item. 66 * @item: List item. Note that the queue is "built" on top of 67 * the bi-directional linked list. 68 * @event_type: Event type. Includes (but is not restricted to) 69 * one of the vxge_hal_event_e {} enumerated types. 70 * @data_size: Size of the enqueued user data. Note that vxge_queue_t 71 * items are allowed to have variable sizes. 72 * @is_critical: For critical events, e.g. ECC. 73 * @context: Opaque (void *) "context", for instance event producer object. 74 * 75 * Item of the vxge_queue_t {}. The queue is protected 76 * in terms of multi-threaded concurrent access. 77 * See also: vxge_queue_t {}. 78 */ 79typedef struct vxge_queue_item_t { 80 vxge_list_t item; 81 vxge_hal_event_e event_type; 82 u32 data_size; 83 u32 is_critical; 84 void *context; 85} vxge_queue_item_t; 86 87/* 88 * function vxge_queued_f - Item-enqueued callback. 89 * @data: Per-queue context independent of the event. E.g., device handle. 90 * @event_type: HAL or ULD-defined event type. Note that HAL own 91 * events are enumerated by vxge_hal_event_e {}. 92 * 93 * Per-queue optional callback. If not NULL, called by HAL each 94 * time an event gets added to the queue. 95 */ 96typedef void (*vxge_queued_f) (void *data, u32 event_type); 97 98/* 99 * struct vxge_queue_t - Protected dynamic queue of variable-size items. 100 * @start_ptr: Points to the start of the queue. 101 * @end_ptr: Points to the end of the queue. 102 * @head_ptr: Points to the head of the queue. It gets changed during queue 103 * produce/consume operations. 104 * @tail_ptr: Points to the tail of the queue. It gets changed during queue 105 * produce/consume operations. 106 * @lock: Lock for queue operations(syncronization purpose). 107 * @pages_initial:Number of pages to be initially allocated at the time 108 * of queue creation. 109 * @pages_max: Max number of pages that can be allocated in the queue. 110 * @pages_current: Number of pages currently allocated 111 * @list_head: Points to the list of queue elements that are produced, but yet 112 * to be consumed. 113 * @hldev: HAL device handle 114 * @pdev: PCI device handle 115 * @irqh: PCI device IRQ handle. 116 * @queued_func: Optional callback function to be called each time a new 117 * item is added to the queue. 118 * @queued_data: Arguments to the callback function. 119 * @has_critical_event: Non-zero, if the queue contains a critical event, 120 * see vxge_hal_event_e {}. 121 * Protected dynamically growing queue. The queue is used to support multiple 122 * producer/consumer type scenarios. The queue is a strict FIFO: first come 123 * first served. 124 * Queue users may "produce" (see vxge_queue_produce()) and "consume" 125 * (see vxge_queue_consume()) items (a.k.a. events) variable sizes. 126 * See also: vxge_queue_item_t {}. 127 */ 128typedef struct vxge_queue_t { 129 void *start_ptr; 130 void *end_ptr; 131 void *head_ptr; 132 void *tail_ptr; 133 spinlock_t lock; 134 u32 pages_initial; 135 u32 pages_max; 136 u32 pages_current; 137 vxge_list_t list_head; 138 vxge_hal_device_h hldev; 139 pci_dev_h pdev; 140 pci_irq_h irqh; 141 vxge_queued_f queued_func; 142 void *queued_data; 143 u32 has_critical_event; 144} vxge_queue_t; 145 146/* ========================== PUBLIC API ================================= */ 147 148/* 149 * vxge_queue_create - Create protected first-in-first-out queue. 150 * @devh: HAL device handle. 151 * @pages_initial: Number of pages to be initially allocated at the 152 * time of queue creation. 153 * @pages_max: Max number of pages that can be allocated in the queue. 154 * @queued_func: Optional callback function to be called each time a new item is 155 * added to the queue. 156 * @queued_data: Argument to the callback function. 157 * 158 * Create protected (fifo) queue. 159 * 160 * Returns: Pointer to vxge_queue_t structure, 161 * NULL - on failure. 162 * 163 * See also: vxge_queue_item_t {}, vxge_queue_destroy(). 164 */ 165vxge_queue_h 166vxge_queue_create(vxge_hal_device_h devh, 167 u32 pages_initial, 168 u32 pages_max, 169 vxge_queued_f queued_func, 170 void *queued_data); 171 172/* 173 * vxge_queue_destroy - Destroy vxge_queue_t object. 174 * @queueh: Queue handle. 175 * 176 * Destroy the specified vxge_queue_t object. 177 * 178 * See also: vxge_queue_item_t {}, vxge_queue_create(). 179 */ 180void 181vxge_queue_destroy(vxge_queue_h queueh); 182 183/* 184 * vxge_queue_item_data - Get item's data. 185 * @item: Queue item. 186 * 187 * Returns: item data(variable size). Note that vxge_queue_t 188 * contains items comprized of a fixed vxge_queue_item_t "header" 189 * and a variable size data. This function returns the variable 190 * user-defined portion of the queue item. 191 */ 192void * 193vxge_queue_item_data(vxge_queue_item_t *item); 194 195/* 196 * vxge_queue_produce - Enqueue an item (see vxge_queue_item_t {}) 197 * into the specified queue. 198 * @queueh: Queue handle. 199 * @event_type: Event type. One of the enumerated event types 200 * that both consumer and producer "understand". 201 * For an example, please refer to vxge_hal_event_e. 202 * @context: Opaque (void *) "context", for instance event producer object. 203 * @is_critical: For critical event, e.g. ECC. 204 * @data_size: Size of the @data. 205 * @data: User data of variable @data_size that is _copied_ into 206 * the new queue item (see vxge_queue_item_t {}). Upon return 207 * from the call the @data memory can be re-used or released. 208 * 209 * Enqueue a new item. 210 * 211 * Returns: VXGE_QUEUE_OK - success. 212 * VXGE_QUEUE_IS_FULL - Queue is full. 213 * VXGE_QUEUE_OUT_OF_MEMORY - Memory allocation failed. 214 * 215 * See also: vxge_queue_item_t {}, vxge_queue_consume(). 216 */ 217vxge_queue_status_e 218vxge_queue_produce(vxge_queue_h queueh, 219 u32 event_type, 220 void *context, 221 u32 is_critical, 222 const u32 data_size, 223 void *data); 224 225/* 226 * vxge_queue_produce_context - Enqueue context. 227 * @queueh: Queue handle. 228 * @event_type: Event type. One of the enumerated event types 229 * that both consumer and producer "understand". 230 * For an example, please refer to vxge_hal_event_e. 231 * @context: Opaque (void *) "context", for instance event producer object. 232 * 233 * Enqueue Context. 234 * 235 * Returns: VXGE_QUEUE_OK - success. 236 * VXGE_QUEUE_IS_EMPTY - Queue is empty. 237 * VXGE_QUEUE_NOT_ENOUGH_SPACE - Requested item size(@data_max_size) 238 * is too small to accomodate an item from the queue. 239 * 240 * See also: vxge_queue_item_t {}, vxge_queue_produce(). 241 */ 242static inline vxge_queue_status_e 243/* LINTED */ 244vxge_queue_produce_context(vxge_queue_h queueh, 245 u32 event_type, 246 void *context) 247{ 248 return (vxge_queue_produce(queueh, event_type, context, 0, 0, 0)); 249} 250 251/* 252 * vxge_queue_consume - Dequeue an item from the specified queue. 253 * @queueh: Queue handle. 254 * @data_max_size: Maximum expected size of the item. 255 * @item: Memory area into which the item is _copied_ upon return 256 * from the function. 257 * 258 * Dequeue an item from the queue. The caller is required to provide 259 * enough space for the item. 260 * 261 * Returns: VXGE_QUEUE_OK - success. 262 * VXGE_QUEUE_IS_EMPTY - Queue is empty. 263 * VXGE_QUEUE_NOT_ENOUGH_SPACE - Requested item size(@data_max_size) 264 * is too small to accomodate an item from the queue. 265 * 266 * See also: vxge_queue_item_t {}, vxge_queue_produce(). 267 */ 268vxge_queue_status_e 269vxge_queue_consume(vxge_queue_h queueh, 270 u32 data_max_size, 271 vxge_queue_item_t *item); 272 273/* 274 * vxge_queue_flush - Flush, or empty, the queue. 275 * @queueh: Queue handle. 276 * 277 * Flush the queue, i.e. make it empty by consuming all events 278 * without invoking the event processing logic (callbacks, etc.) 279 */ 280void 281vxge_queue_flush(vxge_queue_h queueh); 282 283/* 284 * vxge_io_queue_grow - Dynamically increases the size of the queue. 285 * @queueh: Queue handle. 286 * 287 * This function is called in the case of no slot avaialble in the queue 288 * to accomodate the newly received event. 289 * Note that queue cannot grow beyond the max size specified for the 290 * queue. 291 * 292 * Returns VXGE_QUEUE_OK: On success. 293 * VXGE_QUEUE_OUT_OF_MEMORY : No memory is available. 294 */ 295vxge_queue_status_e 296vxge_io_queue_grow(vxge_queue_h qh); 297 298/* 299 * vxge_queue_get_reset_critical - Check for critical events in the queue, 300 * @queueh: Queue handle. 301 * 302 * Check for critical event(s) in the queue, and reset the 303 * "has-critical-event" flag upon return. 304 * Returns: 1 - if the queue contains atleast one critical event. 305 * 0 - If there are no critical events in the queue. 306 */ 307u32 308vxge_queue_get_reset_critical(vxge_queue_h queueh); 309 310__EXTERN_END_DECLS 311 312#endif /* VXGE_QUEUE_H */ 313