4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1985-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Vuid_store.c - Implement the vuid_store.h event storage interface.
33 #include <sys/types.h>
36 #include <sys/systm.h>
38 #include <sys/vuid_event.h>
39 #include <sys/vuid_state.h>
40 #include <sys/vuid_store.h>
42 static void vuid_destroy_seg();
43 static Vuid_seg
* vuid_copy_seg();
44 static Vuid_seg
* vuid_find_seg();
45 static Vuid_value
* vuid_add_value();
46 static Vuid_value
* vuid_find_value();
49 #define vuid_alloc(bytes) \
50 kmem_alloc((bytes), servicing_interrupt())
51 #define vuid_free(ptr, bytes) kmem_free((ptr), (bytes))
53 #define vuid_alloc(bytes) malloc((bytes))
54 #define vuid_free(ptr, bytes) free((ptr))
58 vuid_set_value(client_state_ptr
, event
)
59 Vuid_state
*client_state_ptr
;
60 register Firm_event
*event
;
62 Vuid_seg
**state_ptr
= (Vuid_seg
**)client_state_ptr
;
63 Vuid_seg
*state
= *state_ptr
;
64 register Vuid_seg
*seg
;
65 register Vuid_value
*val_node
;
66 register Vuid_value
*pair_val_node
;
67 register ushort_t offset
= vuid_id_offset(event
->id
);
68 register ushort_t pair
= event
->pair
;
69 int int_bit
, val_original
;
71 /* Get (search for) seg from state assoicated with event */
72 if ((seg
= vuid_find_seg(state
, vuid_id_addr(event
->id
))) ==
74 /* Allocate and initialize new seg for event */
75 seg
= (Vuid_seg
*) vuid_alloc(sizeof (*seg
));
76 bzero((caddr_t
)seg
, sizeof (*seg
));
77 seg
->addr
= vuid_id_addr(event
->id
);
78 /* Add the seg to state */
82 int_bit
= vuid_get_int_bit(seg
, offset
);
83 /* See if no value node and event value is not boolean */
84 if ((!int_bit
) && vuid_int_value(event
->value
)) {
85 (void) vuid_add_value(seg
, offset
);
88 /* If boolean event then set boolean bit */
91 vuid_set_boolean_bit(seg
, offset
);
93 vuid_clear_boolean_bit(seg
, offset
);
95 /* Get (search for) value node (should be there) */
96 val_node
= vuid_find_value(seg
, offset
);
97 val_original
= val_node
->value
;
98 val_node
->value
= event
->value
;
99 switch (event
->pair_type
) {
102 /* See if value node for pair */
103 if (!vuid_get_int_bit(seg
, pair
))
104 (void) vuid_add_value(seg
, pair
);
105 /* Get (search for) value node (should be there) */
106 pair_val_node
= vuid_find_value(seg
, pair
);
107 /* Set pair value to difference */
108 pair_val_node
->value
= event
->value
- val_original
;
111 case FE_PAIR_ABSOLUTE
:
112 /* See if value node for pair */
113 if (!vuid_get_int_bit(seg
, pair
))
114 (void) vuid_add_value(seg
, pair
);
115 /* Get (search for) value node (should be there) */
116 pair_val_node
= vuid_find_value(seg
, pair
);
117 /* Add event value to pair value */
118 pair_val_node
->value
+= event
->value
;
125 /* Recursively call vuid_set_value if there is an associated pair */
126 if (event
->pair_type
== FE_PAIR_SET
) {
127 Firm_event pair_event
;
130 pair_event
.id
= vuid_id_addr(event
->id
) | pair
;
131 pair_event
.pair_type
= FE_PAIR_NONE
;
133 vuid_set_value(client_state_ptr
, &pair_event
);
138 vuid_get_value(client_state
, id
)
139 Vuid_state client_state
;
142 Vuid_seg
*state
= vuid_cstate_to_state(client_state
);
143 register Vuid_seg
*seg
;
144 Vuid_value
*val_node
;
145 register ushort_t offset
= vuid_id_offset(id
);
147 /* Get (search for) seg from state assoicated with id */
148 if ((seg
= vuid_find_seg(state
, vuid_id_addr(id
))) == VUID_SEG_NULL
)
150 /* If boolean event (i.e., no ints bit on) then return boolean value */
151 if (!vuid_get_int_bit(seg
, offset
))
152 return (vuid_get_boolean_bit(seg
, offset
) != 0);
154 /* Get (search for) value node and return value */
155 val_node
= vuid_find_value(seg
, offset
);
156 return (val_node
->value
);
161 vuid_destroy_state(client_state
)
162 Vuid_state client_state
;
164 Vuid_seg
*state
= vuid_cstate_to_state(client_state
);
165 register Vuid_seg
*seg
;
168 for (seg
= state
; seg
; seg
= seg_next
) {
169 seg_next
= seg
->next
;
170 vuid_destroy_seg(seg
);
175 vuid_destroy_seg(seg
)
178 register Vuid_value
*val_node
;
179 Vuid_value
*val_node_next
;
181 for (val_node
= seg
->list
; val_node
; val_node
= val_node_next
) {
182 val_node_next
= val_node
->next
;
183 vuid_free((caddr_t
)val_node
, sizeof (Vuid_value
));
185 vuid_free((caddr_t
)seg
, sizeof (Vuid_seg
));
189 vuid_copy_state(client_state
)
190 Vuid_state client_state
;
192 Vuid_seg
*state
= vuid_cstate_to_state(client_state
);
193 register Vuid_seg
*seg
;
194 Vuid_seg
*new_first_seg
= VUID_SEG_NULL
;
195 register Vuid_seg
*new_previous_seg
= VUID_SEG_NULL
;
196 register Vuid_seg
*new_seg
;
198 for (seg
= state
; seg
; seg
= seg
->next
) {
199 new_seg
= vuid_copy_seg(seg
);
200 /* Remember first seg as state */
201 if (new_first_seg
== VUID_SEG_NULL
)
202 new_first_seg
= new_seg
;
203 /* Link segs together */
204 if (new_previous_seg
!= VUID_SEG_NULL
)
205 new_previous_seg
->next
= new_seg
;
206 /* Remember seg for linking later */
207 new_previous_seg
= new_seg
;
209 return ((Vuid_state
) new_first_seg
);
216 register Vuid_value
*val_node
;
218 register Vuid_value
*new_previous_val
= VUID_VALUE_NULL
;
219 register Vuid_value
*new_val
;
221 /* Allocate and initialize new seg for event */
222 new_seg
= (Vuid_seg
*) vuid_alloc(sizeof (*seg
));
224 /* Terminate new pointer with null */
225 new_seg
->next
= VUID_SEG_NULL
;
226 new_seg
->list
= VUID_VALUE_NULL
;
227 /* Copy list elements */
228 for (val_node
= seg
->list
; val_node
; val_node
= val_node
->next
) {
229 new_val
= (Vuid_value
*) vuid_alloc(sizeof (*new_val
));
230 *new_val
= *val_node
;
231 new_val
->next
= VUID_VALUE_NULL
;
232 /* Remember first value as head of list */
233 if (new_seg
->list
== VUID_VALUE_NULL
)
234 new_seg
->list
= new_val
;
235 /* Link vals together */
236 if (new_previous_val
!= VUID_VALUE_NULL
)
237 new_previous_val
->next
= new_val
;
238 /* Remember val for linking later */
239 new_previous_val
= new_val
;
245 vuid_find_seg(state
, addr
)
249 register Vuid_seg
*seg
;
251 for (seg
= state
; seg
; seg
= seg
->next
) {
252 if (seg
->addr
== addr
)
255 return (VUID_SEG_NULL
);
259 vuid_find_value(seg
, offset
)
263 register Vuid_value
*val_node
;
265 for (val_node
= seg
->list
; val_node
; val_node
= val_node
->next
) {
266 if (vuid_id_offset(val_node
->offset
) == offset
)
269 return (VUID_VALUE_NULL
);
273 vuid_add_value(seg
, offset
)
277 Vuid_value
*list_tmp
;
278 Vuid_value
*val_node
;
280 /* Allocate and initialize new value node for event */
281 val_node
= (Vuid_value
*) vuid_alloc(sizeof (*val_node
));
282 bzero((caddr_t
)val_node
, sizeof (*val_node
));
283 val_node
->offset
= offset
;
284 /* Add the value node to list */
285 list_tmp
= seg
->list
;
286 seg
->list
= val_node
;
287 val_node
->next
= list_tmp
;
288 vuid_set_int_bit(seg
, offset
);
289 /* Clear boolean bit for event */
290 vuid_clear_boolean_bit(seg
, offset
);