1*12967Sgavin.maltby@oracle.com /*
2*12967Sgavin.maltby@oracle.com * CDDL HEADER START
3*12967Sgavin.maltby@oracle.com *
4*12967Sgavin.maltby@oracle.com * The contents of this file are subject to the terms of the
5*12967Sgavin.maltby@oracle.com * Common Development and Distribution License (the "License").
6*12967Sgavin.maltby@oracle.com * You may not use this file except in compliance with the License.
7*12967Sgavin.maltby@oracle.com *
8*12967Sgavin.maltby@oracle.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12967Sgavin.maltby@oracle.com * or http://www.opensolaris.org/os/licensing.
10*12967Sgavin.maltby@oracle.com * See the License for the specific language governing permissions
11*12967Sgavin.maltby@oracle.com * and limitations under the License.
12*12967Sgavin.maltby@oracle.com *
13*12967Sgavin.maltby@oracle.com * When distributing Covered Code, include this CDDL HEADER in each
14*12967Sgavin.maltby@oracle.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12967Sgavin.maltby@oracle.com * If applicable, add the following below this CDDL HEADER, with the
16*12967Sgavin.maltby@oracle.com * fields enclosed by brackets "[]" replaced with your own identifying
17*12967Sgavin.maltby@oracle.com * information: Portions Copyright [yyyy] [name of copyright owner]
18*12967Sgavin.maltby@oracle.com *
19*12967Sgavin.maltby@oracle.com * CDDL HEADER END
20*12967Sgavin.maltby@oracle.com */
21*12967Sgavin.maltby@oracle.com
22*12967Sgavin.maltby@oracle.com /*
23*12967Sgavin.maltby@oracle.com * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12967Sgavin.maltby@oracle.com */
25*12967Sgavin.maltby@oracle.com
26*12967Sgavin.maltby@oracle.com #include <stddef.h>
27*12967Sgavin.maltby@oracle.com #include <strings.h>
28*12967Sgavin.maltby@oracle.com
29*12967Sgavin.maltby@oracle.com #include "../common/sw_impl.h"
30*12967Sgavin.maltby@oracle.com
31*12967Sgavin.maltby@oracle.com /*
32*12967Sgavin.maltby@oracle.com * We maintain a single list of all active cases across all
33*12967Sgavin.maltby@oracle.com * subsidary diagnosis "modules". We also offer some serialization
34*12967Sgavin.maltby@oracle.com * services to them.
35*12967Sgavin.maltby@oracle.com *
36*12967Sgavin.maltby@oracle.com * To open a new case a subsidiary engine should use swde_case_open
37*12967Sgavin.maltby@oracle.com * indicating the subsidiary id (from which we lookup the enum sw_casetype)
38*12967Sgavin.maltby@oracle.com * and, optionally, a pointer to a structure for serialization and its size.
39*12967Sgavin.maltby@oracle.com *
40*12967Sgavin.maltby@oracle.com * For each case opened with swde_case_open we maintain an swde_case_t
41*12967Sgavin.maltby@oracle.com * structure in-core. Embedded in this is the swde_case_data_t with
42*12967Sgavin.maltby@oracle.com * information we need to keep track of and manage this case - it's
43*12967Sgavin.maltby@oracle.com * case type, buffer name used for the sub-de-private data (if any)
44*12967Sgavin.maltby@oracle.com * and the size of the sub-de-private structure. It is this
45*12967Sgavin.maltby@oracle.com * embedded structure which is serialized as the "casedata" buffer,
46*12967Sgavin.maltby@oracle.com * while the subsidiary-private structure is serialized into another buffer
47*12967Sgavin.maltby@oracle.com * "casedata_<casetype-in-hex>".
48*12967Sgavin.maltby@oracle.com *
49*12967Sgavin.maltby@oracle.com * The subsidiary-private data structure, if any, is required to start
50*12967Sgavin.maltby@oracle.com * with a uint32_t recording the data structure version. This
51*12967Sgavin.maltby@oracle.com * version is also specified as an argument to swde_case_open, and
52*12967Sgavin.maltby@oracle.com * we note it in the "casedata" buffer we write out and require
53*12967Sgavin.maltby@oracle.com * a match on restore.
54*12967Sgavin.maltby@oracle.com *
55*12967Sgavin.maltby@oracle.com * When we unserialize we restore our management structure as well as
56*12967Sgavin.maltby@oracle.com * the sub-de-private structure.
57*12967Sgavin.maltby@oracle.com *
58*12967Sgavin.maltby@oracle.com * Here's how serialization works:
59*12967Sgavin.maltby@oracle.com *
60*12967Sgavin.maltby@oracle.com * In swde_case_open we create a case data buffer for the case named
61*12967Sgavin.maltby@oracle.com * SW_CASE_DATA_BUFNAME. We write the buffer out after filling in the
62*12967Sgavin.maltby@oracle.com * structure version and recording the type of case this is, and if there
63*12967Sgavin.maltby@oracle.com * is data for the subsidiary then we call swde_subdata to note the
64*12967Sgavin.maltby@oracle.com * size and version of that data in the case data buf and then to create
65*12967Sgavin.maltby@oracle.com * and write the subdata in a buffer named SW_CASE_DATA_BUFNAME_<casetype>.
66*12967Sgavin.maltby@oracle.com *
67*12967Sgavin.maltby@oracle.com * If the subsidiary updates its case data it is required to call
68*12967Sgavin.maltby@oracle.com * swde_case_data_write. This just calls fmd_buf_write for the subsidiary
69*12967Sgavin.maltby@oracle.com * buffer name.
70*12967Sgavin.maltby@oracle.com *
71*12967Sgavin.maltby@oracle.com * A subsidiary can retrieve its private data buffer for a case using
72*12967Sgavin.maltby@oracle.com * swde_case_data. This also fills a uint32_t with the version of the
73*12967Sgavin.maltby@oracle.com * buffer that we have for this subsidiary; if that is an old version
74*12967Sgavin.maltby@oracle.com * the subsidiary can cast appropriately and/or upgrade the buffer as
75*12967Sgavin.maltby@oracle.com * below.
76*12967Sgavin.maltby@oracle.com *
77*12967Sgavin.maltby@oracle.com * When the host module is reloaded it calls swde_case_init to iterate
78*12967Sgavin.maltby@oracle.com * through all cases we own. For each we call swde_case_unserialize
79*12967Sgavin.maltby@oracle.com * which restores our case tracking data and any subsidiary-private
80*12967Sgavin.maltby@oracle.com * data that our case data notes. We then call swde_case_verify which
81*12967Sgavin.maltby@oracle.com * calls any registered verify function in the subsidiary owner, and if this
82*12967Sgavin.maltby@oracle.com * returns 0 the case is closed.
83*12967Sgavin.maltby@oracle.com *
84*12967Sgavin.maltby@oracle.com * After initial write, we don't usually have to update the
85*12967Sgavin.maltby@oracle.com * SW_CASE_DATA_BUFNAME buffer unless the subsidiary changes the size or
86*12967Sgavin.maltby@oracle.com * version of its private buffer. To do that the subsidiary must call
87*12967Sgavin.maltby@oracle.com * swde_case_data_upgrade. In that function we destroy the old subsidiary
88*12967Sgavin.maltby@oracle.com * buffer and, if there is still a subsidiary data structure, create a
89*12967Sgavin.maltby@oracle.com * new buffer appropriately sized and call swde_subdata to write it out
90*12967Sgavin.maltby@oracle.com * after updating our case structure with new size etc. Finally we write
91*12967Sgavin.maltby@oracle.com * out our updated case data structure.
92*12967Sgavin.maltby@oracle.com */
93*12967Sgavin.maltby@oracle.com
94*12967Sgavin.maltby@oracle.com #define SW_CASE_DATA_BUFNAME "casedata"
95*12967Sgavin.maltby@oracle.com
96*12967Sgavin.maltby@oracle.com #define SW_CASE_DATA_VERSION_INITIAL 1
97*12967Sgavin.maltby@oracle.com #define SW_CASE_DATA_BUFNAMELEN 18 /* 8 + 1 + 8 + 1 */
98*12967Sgavin.maltby@oracle.com typedef struct swde_case_data {
99*12967Sgavin.maltby@oracle.com uint32_t sc_version; /* buffer structure version */
100*12967Sgavin.maltby@oracle.com int32_t sc_type; /* enum sw_casetype */
101*12967Sgavin.maltby@oracle.com uint32_t sc_sub_bufvers; /* version expected in subsidiary */
102*12967Sgavin.maltby@oracle.com char sc_sub_bufname[SW_CASE_DATA_BUFNAMELEN]; /* subsidiary bufname */
103*12967Sgavin.maltby@oracle.com int32_t sc_sub_bufsz; /* subsidiary structure size */
104*12967Sgavin.maltby@oracle.com } swde_case_data_t;
105*12967Sgavin.maltby@oracle.com
106*12967Sgavin.maltby@oracle.com #define SW_CASE_DATA_VERSION SW_CASE_DATA_VERSION_INITIAL
107*12967Sgavin.maltby@oracle.com
108*12967Sgavin.maltby@oracle.com /*
109*12967Sgavin.maltby@oracle.com * In-core case structure.
110*12967Sgavin.maltby@oracle.com */
111*12967Sgavin.maltby@oracle.com typedef struct swde_case {
112*12967Sgavin.maltby@oracle.com fmd_case_t *swc_fmdcase; /* fmd case handle */
113*12967Sgavin.maltby@oracle.com swde_case_data_t swc_data; /* case data for serialization */
114*12967Sgavin.maltby@oracle.com void *swc_subdata; /* subsidiary data for serialization */
115*12967Sgavin.maltby@oracle.com } swde_case_t;
116*12967Sgavin.maltby@oracle.com
117*12967Sgavin.maltby@oracle.com static void
swde_case_associate(fmd_hdl_t * hdl,fmd_case_t * cp,swde_case_t * scp,void * subdata)118*12967Sgavin.maltby@oracle.com swde_case_associate(fmd_hdl_t *hdl, fmd_case_t *cp, swde_case_t *scp,
119*12967Sgavin.maltby@oracle.com void *subdata)
120*12967Sgavin.maltby@oracle.com {
121*12967Sgavin.maltby@oracle.com scp->swc_fmdcase = cp;
122*12967Sgavin.maltby@oracle.com scp->swc_subdata = subdata;
123*12967Sgavin.maltby@oracle.com fmd_case_setspecific(hdl, cp, scp);
124*12967Sgavin.maltby@oracle.com }
125*12967Sgavin.maltby@oracle.com
126*12967Sgavin.maltby@oracle.com static void
swde_case_unserialize(fmd_hdl_t * hdl,fmd_case_t * cp)127*12967Sgavin.maltby@oracle.com swde_case_unserialize(fmd_hdl_t *hdl, fmd_case_t *cp)
128*12967Sgavin.maltby@oracle.com {
129*12967Sgavin.maltby@oracle.com swde_case_t *scp;
130*12967Sgavin.maltby@oracle.com swde_case_data_t *datap;
131*12967Sgavin.maltby@oracle.com void *subdata;
132*12967Sgavin.maltby@oracle.com size_t sz;
133*12967Sgavin.maltby@oracle.com
134*12967Sgavin.maltby@oracle.com scp = fmd_hdl_zalloc(hdl, sizeof (*scp), FMD_SLEEP);
135*12967Sgavin.maltby@oracle.com datap = &scp->swc_data;
136*12967Sgavin.maltby@oracle.com
137*12967Sgavin.maltby@oracle.com fmd_buf_read(hdl, cp, SW_CASE_DATA_BUFNAME, datap, sizeof (*datap));
138*12967Sgavin.maltby@oracle.com
139*12967Sgavin.maltby@oracle.com if (datap->sc_version > SW_CASE_DATA_VERSION_INITIAL) {
140*12967Sgavin.maltby@oracle.com fmd_hdl_free(hdl, scp, sizeof (*scp));
141*12967Sgavin.maltby@oracle.com return;
142*12967Sgavin.maltby@oracle.com }
143*12967Sgavin.maltby@oracle.com
144*12967Sgavin.maltby@oracle.com if ((sz = datap->sc_sub_bufsz) != 0) {
145*12967Sgavin.maltby@oracle.com subdata = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
146*12967Sgavin.maltby@oracle.com fmd_buf_read(hdl, cp, datap->sc_sub_bufname, subdata, sz);
147*12967Sgavin.maltby@oracle.com
148*12967Sgavin.maltby@oracle.com if (*((uint32_t *)subdata) != datap->sc_sub_bufvers) {
149*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "unserialize: expected subdata "
150*12967Sgavin.maltby@oracle.com "version %u but received %u\n",
151*12967Sgavin.maltby@oracle.com datap->sc_sub_bufvers, *((uint32_t *)subdata));
152*12967Sgavin.maltby@oracle.com }
153*12967Sgavin.maltby@oracle.com }
154*12967Sgavin.maltby@oracle.com
155*12967Sgavin.maltby@oracle.com swde_case_associate(hdl, cp, scp, subdata);
156*12967Sgavin.maltby@oracle.com }
157*12967Sgavin.maltby@oracle.com
158*12967Sgavin.maltby@oracle.com static void
swde_subdata(fmd_hdl_t * hdl,fmd_case_t * cp,enum sw_casetype type,swde_case_t * scp,uint32_t subdata_vers,void * subdata,size_t subdata_sz)159*12967Sgavin.maltby@oracle.com swde_subdata(fmd_hdl_t *hdl, fmd_case_t *cp, enum sw_casetype type,
160*12967Sgavin.maltby@oracle.com swde_case_t *scp, uint32_t subdata_vers, void *subdata, size_t subdata_sz)
161*12967Sgavin.maltby@oracle.com {
162*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
163*12967Sgavin.maltby@oracle.com
164*12967Sgavin.maltby@oracle.com if (*((uint32_t *)subdata) != subdata_vers)
165*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "swde_subdata: subdata version "
166*12967Sgavin.maltby@oracle.com "does not match argument\n");
167*12967Sgavin.maltby@oracle.com
168*12967Sgavin.maltby@oracle.com (void) snprintf(datap->sc_sub_bufname, sizeof (datap->sc_sub_bufname),
169*12967Sgavin.maltby@oracle.com "%s_%08x", SW_CASE_DATA_BUFNAME, type);
170*12967Sgavin.maltby@oracle.com
171*12967Sgavin.maltby@oracle.com datap->sc_sub_bufsz = subdata_sz;
172*12967Sgavin.maltby@oracle.com datap->sc_sub_bufvers = subdata_vers;
173*12967Sgavin.maltby@oracle.com fmd_buf_create(hdl, cp, datap->sc_sub_bufname, subdata_sz);
174*12967Sgavin.maltby@oracle.com fmd_buf_write(hdl, cp, datap->sc_sub_bufname, subdata, subdata_sz);
175*12967Sgavin.maltby@oracle.com }
176*12967Sgavin.maltby@oracle.com
177*12967Sgavin.maltby@oracle.com fmd_case_t *
swde_case_open(fmd_hdl_t * hdl,id_t who,char * req_uuid,uint32_t subdata_vers,void * subdata,size_t subdata_sz)178*12967Sgavin.maltby@oracle.com swde_case_open(fmd_hdl_t *hdl, id_t who, char *req_uuid,
179*12967Sgavin.maltby@oracle.com uint32_t subdata_vers, void *subdata, size_t subdata_sz)
180*12967Sgavin.maltby@oracle.com {
181*12967Sgavin.maltby@oracle.com enum sw_casetype ct = sw_id_to_casetype(hdl, who);
182*12967Sgavin.maltby@oracle.com swde_case_data_t *datap;
183*12967Sgavin.maltby@oracle.com swde_case_t *scp;
184*12967Sgavin.maltby@oracle.com fmd_case_t *cp;
185*12967Sgavin.maltby@oracle.com
186*12967Sgavin.maltby@oracle.com if (ct == SW_CASE_NONE)
187*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "swde_case_open for type SW_CASE_NONE\n");
188*12967Sgavin.maltby@oracle.com
189*12967Sgavin.maltby@oracle.com if (subdata != NULL && subdata_sz <= sizeof (uint32_t) ||
190*12967Sgavin.maltby@oracle.com subdata_sz != 0 && subdata == NULL)
191*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "swde_case_open: bad subdata\n", ct);
192*12967Sgavin.maltby@oracle.com
193*12967Sgavin.maltby@oracle.com scp = fmd_hdl_zalloc(hdl, sizeof (*scp), FMD_SLEEP);
194*12967Sgavin.maltby@oracle.com datap = &scp->swc_data;
195*12967Sgavin.maltby@oracle.com
196*12967Sgavin.maltby@oracle.com if (req_uuid == NULL) {
197*12967Sgavin.maltby@oracle.com cp = fmd_case_open(hdl, (void *)scp);
198*12967Sgavin.maltby@oracle.com } else {
199*12967Sgavin.maltby@oracle.com cp = fmd_case_open_uuid(hdl, req_uuid, (void *)scp);
200*12967Sgavin.maltby@oracle.com if (cp == NULL) {
201*12967Sgavin.maltby@oracle.com fmd_hdl_free(hdl, scp, sizeof (*scp));
202*12967Sgavin.maltby@oracle.com return (NULL);
203*12967Sgavin.maltby@oracle.com }
204*12967Sgavin.maltby@oracle.com }
205*12967Sgavin.maltby@oracle.com
206*12967Sgavin.maltby@oracle.com fmd_buf_create(hdl, cp, SW_CASE_DATA_BUFNAME, sizeof (*datap));
207*12967Sgavin.maltby@oracle.com datap->sc_version = SW_CASE_DATA_VERSION_INITIAL;
208*12967Sgavin.maltby@oracle.com datap->sc_type = ct;
209*12967Sgavin.maltby@oracle.com
210*12967Sgavin.maltby@oracle.com if (subdata)
211*12967Sgavin.maltby@oracle.com swde_subdata(hdl, cp, ct, scp, subdata_vers, subdata,
212*12967Sgavin.maltby@oracle.com subdata_sz);
213*12967Sgavin.maltby@oracle.com
214*12967Sgavin.maltby@oracle.com fmd_buf_write(hdl, cp, SW_CASE_DATA_BUFNAME, datap, sizeof (*datap));
215*12967Sgavin.maltby@oracle.com swde_case_associate(hdl, cp, scp, subdata);
216*12967Sgavin.maltby@oracle.com
217*12967Sgavin.maltby@oracle.com return (cp);
218*12967Sgavin.maltby@oracle.com }
219*12967Sgavin.maltby@oracle.com
220*12967Sgavin.maltby@oracle.com /*
221*12967Sgavin.maltby@oracle.com * fmdo_close entry point for software-diagnosis
222*12967Sgavin.maltby@oracle.com */
223*12967Sgavin.maltby@oracle.com void
swde_close(fmd_hdl_t * hdl,fmd_case_t * cp)224*12967Sgavin.maltby@oracle.com swde_close(fmd_hdl_t *hdl, fmd_case_t *cp)
225*12967Sgavin.maltby@oracle.com {
226*12967Sgavin.maltby@oracle.com swde_case_t *scp = fmd_case_getspecific(hdl, cp);
227*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
228*12967Sgavin.maltby@oracle.com swsub_case_close_func_t *closefunc;
229*12967Sgavin.maltby@oracle.com
230*12967Sgavin.maltby@oracle.com if ((closefunc = sw_sub_case_close_func(hdl, datap->sc_type)) != NULL)
231*12967Sgavin.maltby@oracle.com closefunc(hdl, cp);
232*12967Sgavin.maltby@oracle.com
233*12967Sgavin.maltby@oracle.com /*
234*12967Sgavin.maltby@oracle.com * Now that the sub-de has had a chance to clean up, do some ourselves.
235*12967Sgavin.maltby@oracle.com * Note that we free the sub-de-private subdata structure.
236*12967Sgavin.maltby@oracle.com */
237*12967Sgavin.maltby@oracle.com
238*12967Sgavin.maltby@oracle.com if (scp->swc_subdata) {
239*12967Sgavin.maltby@oracle.com fmd_hdl_free(hdl, scp->swc_subdata, datap->sc_sub_bufsz);
240*12967Sgavin.maltby@oracle.com fmd_buf_destroy(hdl, cp, datap->sc_sub_bufname);
241*12967Sgavin.maltby@oracle.com }
242*12967Sgavin.maltby@oracle.com
243*12967Sgavin.maltby@oracle.com fmd_buf_destroy(hdl, cp, SW_CASE_DATA_BUFNAME);
244*12967Sgavin.maltby@oracle.com
245*12967Sgavin.maltby@oracle.com fmd_hdl_free(hdl, scp, sizeof (*scp));
246*12967Sgavin.maltby@oracle.com }
247*12967Sgavin.maltby@oracle.com
248*12967Sgavin.maltby@oracle.com fmd_case_t *
swde_case_first(fmd_hdl_t * hdl,id_t who)249*12967Sgavin.maltby@oracle.com swde_case_first(fmd_hdl_t *hdl, id_t who)
250*12967Sgavin.maltby@oracle.com {
251*12967Sgavin.maltby@oracle.com enum sw_casetype ct = sw_id_to_casetype(hdl, who);
252*12967Sgavin.maltby@oracle.com swde_case_t *scp;
253*12967Sgavin.maltby@oracle.com fmd_case_t *cp;
254*12967Sgavin.maltby@oracle.com
255*12967Sgavin.maltby@oracle.com if (ct == SW_CASE_NONE)
256*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "swde_case_first for type SW_CASE_NONE\n");
257*12967Sgavin.maltby@oracle.com
258*12967Sgavin.maltby@oracle.com for (cp = fmd_case_next(hdl, NULL); cp; cp = fmd_case_next(hdl, cp)) {
259*12967Sgavin.maltby@oracle.com scp = fmd_case_getspecific(hdl, cp);
260*12967Sgavin.maltby@oracle.com if (scp->swc_data.sc_type == ct)
261*12967Sgavin.maltby@oracle.com break;
262*12967Sgavin.maltby@oracle.com }
263*12967Sgavin.maltby@oracle.com
264*12967Sgavin.maltby@oracle.com return (cp);
265*12967Sgavin.maltby@oracle.com }
266*12967Sgavin.maltby@oracle.com
267*12967Sgavin.maltby@oracle.com fmd_case_t *
swde_case_next(fmd_hdl_t * hdl,fmd_case_t * lastcp)268*12967Sgavin.maltby@oracle.com swde_case_next(fmd_hdl_t *hdl, fmd_case_t *lastcp)
269*12967Sgavin.maltby@oracle.com {
270*12967Sgavin.maltby@oracle.com swde_case_t *scp;
271*12967Sgavin.maltby@oracle.com fmd_case_t *cp;
272*12967Sgavin.maltby@oracle.com int ct;
273*12967Sgavin.maltby@oracle.com
274*12967Sgavin.maltby@oracle.com if (lastcp == NULL)
275*12967Sgavin.maltby@oracle.com fmd_hdl_abort(hdl, "swde_case_next called for NULL lastcp\n");
276*12967Sgavin.maltby@oracle.com
277*12967Sgavin.maltby@oracle.com scp = fmd_case_getspecific(hdl, lastcp);
278*12967Sgavin.maltby@oracle.com ct = scp->swc_data.sc_type;
279*12967Sgavin.maltby@oracle.com
280*12967Sgavin.maltby@oracle.com cp = lastcp;
281*12967Sgavin.maltby@oracle.com while ((cp = fmd_case_next(hdl, cp)) != NULL) {
282*12967Sgavin.maltby@oracle.com scp = fmd_case_getspecific(hdl, cp);
283*12967Sgavin.maltby@oracle.com if (scp->swc_data.sc_type == ct)
284*12967Sgavin.maltby@oracle.com break;
285*12967Sgavin.maltby@oracle.com }
286*12967Sgavin.maltby@oracle.com
287*12967Sgavin.maltby@oracle.com return (cp);
288*12967Sgavin.maltby@oracle.com }
289*12967Sgavin.maltby@oracle.com
290*12967Sgavin.maltby@oracle.com void *
swde_case_data(fmd_hdl_t * hdl,fmd_case_t * cp,uint32_t * svp)291*12967Sgavin.maltby@oracle.com swde_case_data(fmd_hdl_t *hdl, fmd_case_t *cp, uint32_t *svp)
292*12967Sgavin.maltby@oracle.com {
293*12967Sgavin.maltby@oracle.com swde_case_t *scp = fmd_case_getspecific(hdl, cp);
294*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
295*12967Sgavin.maltby@oracle.com
296*12967Sgavin.maltby@oracle.com if (svp != NULL && scp->swc_subdata)
297*12967Sgavin.maltby@oracle.com *svp = datap->sc_sub_bufvers;
298*12967Sgavin.maltby@oracle.com
299*12967Sgavin.maltby@oracle.com return (scp->swc_subdata);
300*12967Sgavin.maltby@oracle.com }
301*12967Sgavin.maltby@oracle.com
302*12967Sgavin.maltby@oracle.com void
swde_case_data_write(fmd_hdl_t * hdl,fmd_case_t * cp)303*12967Sgavin.maltby@oracle.com swde_case_data_write(fmd_hdl_t *hdl, fmd_case_t *cp)
304*12967Sgavin.maltby@oracle.com {
305*12967Sgavin.maltby@oracle.com swde_case_t *scp = fmd_case_getspecific(hdl, cp);
306*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
307*12967Sgavin.maltby@oracle.com
308*12967Sgavin.maltby@oracle.com if (scp->swc_subdata == NULL)
309*12967Sgavin.maltby@oracle.com return;
310*12967Sgavin.maltby@oracle.com
311*12967Sgavin.maltby@oracle.com fmd_buf_write(hdl, cp, scp->swc_data.sc_sub_bufname,
312*12967Sgavin.maltby@oracle.com scp->swc_subdata, datap->sc_sub_bufsz);
313*12967Sgavin.maltby@oracle.com }
314*12967Sgavin.maltby@oracle.com
315*12967Sgavin.maltby@oracle.com void
swde_case_data_upgrade(fmd_hdl_t * hdl,fmd_case_t * cp,uint32_t subdata_vers,void * subdata,size_t subdata_sz)316*12967Sgavin.maltby@oracle.com swde_case_data_upgrade(fmd_hdl_t *hdl, fmd_case_t *cp, uint32_t subdata_vers,
317*12967Sgavin.maltby@oracle.com void *subdata, size_t subdata_sz)
318*12967Sgavin.maltby@oracle.com {
319*12967Sgavin.maltby@oracle.com swde_case_t *scp = fmd_case_getspecific(hdl, cp);
320*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
321*12967Sgavin.maltby@oracle.com
322*12967Sgavin.maltby@oracle.com if (scp->swc_subdata) {
323*12967Sgavin.maltby@oracle.com fmd_buf_destroy(hdl, cp, datap->sc_sub_bufname);
324*12967Sgavin.maltby@oracle.com fmd_hdl_free(hdl, scp->swc_subdata, datap->sc_sub_bufsz);
325*12967Sgavin.maltby@oracle.com scp->swc_subdata = NULL;
326*12967Sgavin.maltby@oracle.com datap->sc_sub_bufsz = 0;
327*12967Sgavin.maltby@oracle.com datap->sc_sub_bufname[0] = '\0';
328*12967Sgavin.maltby@oracle.com }
329*12967Sgavin.maltby@oracle.com
330*12967Sgavin.maltby@oracle.com if (subdata != NULL) {
331*12967Sgavin.maltby@oracle.com scp->swc_subdata = subdata;
332*12967Sgavin.maltby@oracle.com swde_subdata(hdl, cp, datap->sc_type, scp, subdata_vers,
333*12967Sgavin.maltby@oracle.com subdata, subdata_sz);
334*12967Sgavin.maltby@oracle.com }
335*12967Sgavin.maltby@oracle.com
336*12967Sgavin.maltby@oracle.com fmd_buf_write(hdl, scp->swc_fmdcase, SW_CASE_DATA_BUFNAME,
337*12967Sgavin.maltby@oracle.com datap, sizeof (*datap));
338*12967Sgavin.maltby@oracle.com }
339*12967Sgavin.maltby@oracle.com
340*12967Sgavin.maltby@oracle.com static void
swde_case_verify(fmd_hdl_t * hdl,fmd_case_t * cp)341*12967Sgavin.maltby@oracle.com swde_case_verify(fmd_hdl_t *hdl, fmd_case_t *cp)
342*12967Sgavin.maltby@oracle.com {
343*12967Sgavin.maltby@oracle.com swde_case_t *scp = fmd_case_getspecific(hdl, cp);
344*12967Sgavin.maltby@oracle.com swde_case_data_t *datap = &scp->swc_data;
345*12967Sgavin.maltby@oracle.com sw_case_vrfy_func_t *vrfy_func;
346*12967Sgavin.maltby@oracle.com
347*12967Sgavin.maltby@oracle.com if ((vrfy_func = sw_sub_case_vrfy_func(hdl, datap->sc_type)) != NULL) {
348*12967Sgavin.maltby@oracle.com if (vrfy_func(hdl, cp) == 0)
349*12967Sgavin.maltby@oracle.com fmd_case_close(hdl, cp);
350*12967Sgavin.maltby@oracle.com }
351*12967Sgavin.maltby@oracle.com }
352*12967Sgavin.maltby@oracle.com
353*12967Sgavin.maltby@oracle.com void
swde_case_init(fmd_hdl_t * hdl)354*12967Sgavin.maltby@oracle.com swde_case_init(fmd_hdl_t *hdl)
355*12967Sgavin.maltby@oracle.com {
356*12967Sgavin.maltby@oracle.com fmd_case_t *cp;
357*12967Sgavin.maltby@oracle.com
358*12967Sgavin.maltby@oracle.com for (cp = fmd_case_next(hdl, NULL); cp; cp = fmd_case_next(hdl, cp)) {
359*12967Sgavin.maltby@oracle.com swde_case_unserialize(hdl, cp);
360*12967Sgavin.maltby@oracle.com swde_case_verify(hdl, cp);
361*12967Sgavin.maltby@oracle.com }
362*12967Sgavin.maltby@oracle.com }
363*12967Sgavin.maltby@oracle.com
364*12967Sgavin.maltby@oracle.com /*ARGSUSED*/
365*12967Sgavin.maltby@oracle.com void
swde_case_fini(fmd_hdl_t * hdl)366*12967Sgavin.maltby@oracle.com swde_case_fini(fmd_hdl_t *hdl)
367*12967Sgavin.maltby@oracle.com {
368*12967Sgavin.maltby@oracle.com }
369