1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright (c) 2002-2006 Neterion, Inc.
*/
#ifndef XGE_QUEUE_H
#define XGE_QUEUE_H
#include "xge-os-pal.h"
#include "xge-defs.h"
#include "xge-list.h"
#include "xgehal-event.h"
__EXTERN_BEGIN_DECLS
#define XGE_QUEUE_BUF_SIZE 0x1000
#define XGE_DEFAULT_EVENT_MAX_DATA_SIZE 16
/**
* enum xge_queue_status_e - Enumerates return codes of the xge_queue
* manipulation APIs.
* @XGE_QUEUE_IS_FULL: Queue is full, need to grow.
* @XGE_QUEUE_IS_EMPTY: Queue is empty.
* @XGE_QUEUE_OUT_OF_MEMORY: Out of memory.
* @XGE_QUEUE_NOT_ENOUGH_SPACE: Exceeded specified event size,
* see xge_queue_consume().
* @XGE_QUEUE_OK: Neither one of the codes listed above.
*
* Enumerates return codes of xge_queue_consume()
* and xge_queue_produce() APIs.
*/
typedef enum xge_queue_status_e {
XGE_QUEUE_OK = 0,
XGE_QUEUE_IS_FULL = 1,
XGE_QUEUE_IS_EMPTY = 2,
XGE_QUEUE_OUT_OF_MEMORY = 3,
XGE_QUEUE_NOT_ENOUGH_SPACE = 4
} xge_queue_status_e;
typedef void* xge_queue_h;
/**
* struct xge_queue_item_t - Queue item.
* @item: List item. Note that the queue is "built" on top of
* the bi-directional linked list.
* @event_type: Event type. Includes (but is not restricted to)
* one of the xge_hal_event_e{} enumerated types.
* @data_size: Size of the enqueued user data. Note that xge_queue_t
* items are allowed to have variable sizes.
* @is_critical: For critical events, e.g. ECC.
* @context: Opaque (void*) "context", for instance event producer object.
*
* Item of the xge_queue_t{}. The queue is protected
* in terms of multi-threaded concurrent access.
* See also: xge_queue_t{}.
*/
typedef struct xge_queue_item_t {
xge_list_t item;
xge_hal_event_e event_type;
int data_size;
int is_critical;
void *context;
} xge_queue_item_t;
/**
* function xge_queued_f - Item-enqueued callback.
* @data: Per-queue context independent of the event. E.g., device handle.
* @event_type: HAL or ULD-defined event type. Note that HAL own
* events are enumerated by xge_hal_event_e{}.
*
* Per-queue optional callback. If not NULL, called by HAL each
* time an event gets added to the queue.
*/
typedef void (*xge_queued_f) (void *data, int event_type);
/**
* struct xge_queue_t - Protected dynamic queue of variable-size items.
* @start_ptr: Points to the start of the queue.
* @end_ptr: Points to the end of the queue.
* @head_ptr: Points to the head of the queue. It gets changed during queue
* produce/consume operations.
* @tail_ptr: Points to the tail of the queue. It gets changed during queue
* produce/consume operations.
* @lock: Lock for queue operations(syncronization purpose).
* @pages_initial:Number of pages to be initially allocated at the time
* of queue creation.
* @pages_max: Max number of pages that can be allocated in the queue.
* @pages_current: Number of pages currently allocated
* @list_head: Points to the list of queue elements that are produced, but yet
* to be consumed.
* @signal_callback: (TODO)
* @pdev: PCI device handle
* @irqh: PCI device IRQ handle.
* @queued_func: Optional callback function to be called each time a new
* item is added to the queue.
* @queued_data: Arguments to the callback function.
* @has_critical_event: Non-zero, if the queue contains a critical event,
* see xge_hal_event_e{}.
* Protected dynamically growing queue. The queue is used to support multiple
* producer/consumer type scenarios. The queue is a strict FIFO: first come
* first served.
* Queue users may "produce" (see xge_queue_produce()) and "consume"
* (see xge_queue_consume()) items (a.k.a. events) variable sizes.
* See also: xge_queue_item_t{}.
*/
typedef struct xge_queue_t {
void *start_ptr;
void *end_ptr;
void *head_ptr;
void *tail_ptr;
spinlock_t lock;
unsigned int pages_initial;
unsigned int pages_max;
unsigned int pages_current;
xge_list_t list_head;
pci_dev_h pdev;
pci_irq_h irqh;
xge_queued_f queued_func;
void *queued_data;
int has_critical_event;
} xge_queue_t;
/* ========================== PUBLIC API ================================= */
xge_queue_h xge_queue_create(pci_dev_h pdev, pci_irq_h irqh, int pages_initial,
int pages_max, xge_queued_f queued_func, void *queued_data);
void xge_queue_destroy(xge_queue_h queueh);
void* xge_queue_item_data(xge_queue_item_t *item);
xge_queue_status_e
xge_queue_produce(xge_queue_h queueh, int event_type, void *context,
int is_critical, const int data_size, void *data);
static inline xge_queue_status_e
xge_queue_produce_context(xge_queue_h queueh, int event_type, void *context) {
return xge_queue_produce(queueh, event_type, context, 0, 0, 0);
}
xge_queue_status_e xge_queue_consume(xge_queue_h queueh, int data_max_size,
xge_queue_item_t *item);
void xge_queue_flush(xge_queue_h queueh);
/* ========================== PRIVATE API ================================= */
xge_queue_status_e __io_queue_grow(xge_queue_h qh);
int __queue_get_reset_critical (xge_queue_h qh);
__EXTERN_END_DECLS
#endif /* XGE_QUEUE_H */
|