xref: /onnv-gate/usr/src/uts/common/avs/ns/sdbc/safestore_ram.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM /*
27*7836SJohn.Forte@Sun.COM  * RAM Safe Store Module
28*7836SJohn.Forte@Sun.COM  */
29*7836SJohn.Forte@Sun.COM 
30*7836SJohn.Forte@Sun.COM #include <sys/types.h>
31*7836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
32*7836SJohn.Forte@Sun.COM #include <sys/kmem.h>
33*7836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
34*7836SJohn.Forte@Sun.COM #include <sys/errno.h>
35*7836SJohn.Forte@Sun.COM 
36*7836SJohn.Forte@Sun.COM #include <sys/nsc_thread.h>
37*7836SJohn.Forte@Sun.COM #include "sd_cache.h"
38*7836SJohn.Forte@Sun.COM #include "sd_trace.h"
39*7836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
40*7836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_k.h>
41*7836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
42*7836SJohn.Forte@Sun.COM 
43*7836SJohn.Forte@Sun.COM #include "safestore.h"
44*7836SJohn.Forte@Sun.COM #include "safestore_impl.h"
45*7836SJohn.Forte@Sun.COM #include "safestore_ram.h"
46*7836SJohn.Forte@Sun.COM 
47*7836SJohn.Forte@Sun.COM extern void _sd_print(int level, char *fmt, ...);
48*7836SJohn.Forte@Sun.COM 
49*7836SJohn.Forte@Sun.COM static int ss_ram_configure(ss_common_config_t *, spcs_s_info_t);
50*7836SJohn.Forte@Sun.COM static int ss_ram_deconfigure(int);
51*7836SJohn.Forte@Sun.COM static int ss_ram_getvdir(const ss_vdirkey_t *, ss_vdir_t *);
52*7836SJohn.Forte@Sun.COM static int ss_ram_getvdirent(const ss_vdir_t *, ss_voldata_t *);
53*7836SJohn.Forte@Sun.COM static int ss_ram_getvol(ss_voldata_t *);
54*7836SJohn.Forte@Sun.COM static int ss_ram_setvol(const ss_voldata_t *);
55*7836SJohn.Forte@Sun.COM static int ss_ram_getcdir(const ss_cdirkey_t *, ss_cdir_t *);
56*7836SJohn.Forte@Sun.COM static int ss_ram_getcdirent(ss_cdir_t *, ss_centry_info_t *);
57*7836SJohn.Forte@Sun.COM static int ss_ram_allocresource(int, int *, ss_resourcelist_t **);
58*7836SJohn.Forte@Sun.COM static void ss_ram_deallocresource(ss_resource_t *);
59*7836SJohn.Forte@Sun.COM static int ss_ram_getresource(ss_resourcelist_t **, ss_resource_t **);
60*7836SJohn.Forte@Sun.COM static int ss_ram_getcentry(ss_centry_info_t *);
61*7836SJohn.Forte@Sun.COM static int ss_ram_setcentry(const ss_centry_info_t *);
62*7836SJohn.Forte@Sun.COM static int ss_ram_cblock_read(const ss_resource_t *, void *, int, int);
63*7836SJohn.Forte@Sun.COM static int ss_ram_cblock_write(const ss_resource_t *, const void *, int, int);
64*7836SJohn.Forte@Sun.COM static int ss_ram_ctl(uint_t, uintptr_t);
65*7836SJohn.Forte@Sun.COM 
66*7836SJohn.Forte@Sun.COM 
67*7836SJohn.Forte@Sun.COM safestore_ops_t ss_ram_ops = {
68*7836SJohn.Forte@Sun.COM 	"safestore_ram",
69*7836SJohn.Forte@Sun.COM 	SS_M_RAM | SS_T_NONE,
70*7836SJohn.Forte@Sun.COM 	0,
71*7836SJohn.Forte@Sun.COM 	ss_ram_configure,
72*7836SJohn.Forte@Sun.COM 	ss_ram_deconfigure,
73*7836SJohn.Forte@Sun.COM 	ss_ram_getvdir,
74*7836SJohn.Forte@Sun.COM 	ss_ram_getvdirent,
75*7836SJohn.Forte@Sun.COM 	ss_ram_getvol,
76*7836SJohn.Forte@Sun.COM 	ss_ram_setvol,
77*7836SJohn.Forte@Sun.COM 	ss_ram_getcdir,
78*7836SJohn.Forte@Sun.COM 	ss_ram_getcdirent,
79*7836SJohn.Forte@Sun.COM 	ss_ram_allocresource,
80*7836SJohn.Forte@Sun.COM 	ss_ram_deallocresource,
81*7836SJohn.Forte@Sun.COM 	ss_ram_getresource,
82*7836SJohn.Forte@Sun.COM 	ss_ram_getcentry,
83*7836SJohn.Forte@Sun.COM 	ss_ram_setcentry,
84*7836SJohn.Forte@Sun.COM 	ss_ram_cblock_read,
85*7836SJohn.Forte@Sun.COM 	ss_ram_cblock_write,
86*7836SJohn.Forte@Sun.COM 	ss_ram_ctl
87*7836SJohn.Forte@Sun.COM };
88*7836SJohn.Forte@Sun.COM 
89*7836SJohn.Forte@Sun.COM static void ss_ram_vol_deconfigure();
90*7836SJohn.Forte@Sun.COM static int ss_ram_vol_configure(int);
91*7836SJohn.Forte@Sun.COM static int ss_ram_wctl_configure();
92*7836SJohn.Forte@Sun.COM static void ss_ram_wctl_deconfigure(void);
93*7836SJohn.Forte@Sun.COM static int ss_ram_deconfigure_locked();
94*7836SJohn.Forte@Sun.COM 
95*7836SJohn.Forte@Sun.COM static kmutex_t ss_ram_config_lock;
96*7836SJohn.Forte@Sun.COM 
97*7836SJohn.Forte@Sun.COM static ss_common_config_t ss_ramcommon_config;
98*7836SJohn.Forte@Sun.COM static ss_ram_config_t ss_ram_config;
99*7836SJohn.Forte@Sun.COM 
100*7836SJohn.Forte@Sun.COM static char default_cblock [8192];
101*7836SJohn.Forte@Sun.COM 
102*7836SJohn.Forte@Sun.COM 
103*7836SJohn.Forte@Sun.COM #define	MEGABYTE (1024*1024)
104*7836SJohn.Forte@Sun.COM 
105*7836SJohn.Forte@Sun.COM void
ss_ram_init()106*7836SJohn.Forte@Sun.COM ss_ram_init()
107*7836SJohn.Forte@Sun.COM {
108*7836SJohn.Forte@Sun.COM 	mutex_init(&ss_ram_config_lock, NULL, MUTEX_DRIVER, NULL);
109*7836SJohn.Forte@Sun.COM 	bzero(&ss_ram_config, sizeof (ss_ram_config_t));
110*7836SJohn.Forte@Sun.COM 	bzero(&ss_ramcommon_config, sizeof (ss_common_config_t));
111*7836SJohn.Forte@Sun.COM 	sst_register_mod(&ss_ram_ops);
112*7836SJohn.Forte@Sun.COM 
113*7836SJohn.Forte@Sun.COM 	ss_ram_config.ss_configured = SS_INITTED;
114*7836SJohn.Forte@Sun.COM }
115*7836SJohn.Forte@Sun.COM 
116*7836SJohn.Forte@Sun.COM void
ss_ram_deinit()117*7836SJohn.Forte@Sun.COM ss_ram_deinit()
118*7836SJohn.Forte@Sun.COM {
119*7836SJohn.Forte@Sun.COM 	mutex_destroy(&ss_ram_config_lock);
120*7836SJohn.Forte@Sun.COM 	sst_unregister_mod(&ss_ram_ops);
121*7836SJohn.Forte@Sun.COM }
122*7836SJohn.Forte@Sun.COM 
123*7836SJohn.Forte@Sun.COM 
124*7836SJohn.Forte@Sun.COM /* ARGSUSED */
125*7836SJohn.Forte@Sun.COM static int
ss_ram_configure(ss_common_config_t * clientptr,spcs_s_info_t kstatus)126*7836SJohn.Forte@Sun.COM ss_ram_configure(ss_common_config_t *clientptr, spcs_s_info_t kstatus)
127*7836SJohn.Forte@Sun.COM {
128*7836SJohn.Forte@Sun.COM 
129*7836SJohn.Forte@Sun.COM 	if (clientptr->ssc_wsize == 0) /* choose a default? */
130*7836SJohn.Forte@Sun.COM 		return (EINVAL);
131*7836SJohn.Forte@Sun.COM 
132*7836SJohn.Forte@Sun.COM 	mutex_enter(&ss_ram_config_lock);
133*7836SJohn.Forte@Sun.COM 
134*7836SJohn.Forte@Sun.COM 	/* read in the parameters */
135*7836SJohn.Forte@Sun.COM 	bcopy(clientptr, &ss_ramcommon_config, sizeof (ss_common_config_t));
136*7836SJohn.Forte@Sun.COM 
137*7836SJohn.Forte@Sun.COM 	/* set the page size */
138*7836SJohn.Forte@Sun.COM 	ss_ramcommon_config.ssc_ss_psize = BLK_SIZE(1);
139*7836SJohn.Forte@Sun.COM 
140*7836SJohn.Forte@Sun.COM 	/* initialize client page size if not set */
141*7836SJohn.Forte@Sun.COM 	if (ss_ramcommon_config.ssc_client_psize == 0)
142*7836SJohn.Forte@Sun.COM 		ss_ramcommon_config.ssc_client_psize =
143*7836SJohn.Forte@Sun.COM 					ss_ramcommon_config.ssc_ss_psize;
144*7836SJohn.Forte@Sun.COM 
145*7836SJohn.Forte@Sun.COM 	/* setup volume directory */
146*7836SJohn.Forte@Sun.COM 	if (ss_ram_vol_configure(clientptr->ssc_maxfiles)) {
147*7836SJohn.Forte@Sun.COM 		(void) ss_ram_deconfigure_locked();
148*7836SJohn.Forte@Sun.COM 		mutex_exit(&ss_ram_config_lock);
149*7836SJohn.Forte@Sun.COM 		return (SDBC_ENONETMEM);
150*7836SJohn.Forte@Sun.COM 	}
151*7836SJohn.Forte@Sun.COM 
152*7836SJohn.Forte@Sun.COM 	/* setup write q */
153*7836SJohn.Forte@Sun.COM 	if (ss_ram_wctl_configure()) {
154*7836SJohn.Forte@Sun.COM 		(void) ss_ram_deconfigure_locked();
155*7836SJohn.Forte@Sun.COM 		mutex_exit(&ss_ram_config_lock);
156*7836SJohn.Forte@Sun.COM 		return (SDBC_ENONETMEM);
157*7836SJohn.Forte@Sun.COM 	}
158*7836SJohn.Forte@Sun.COM 
159*7836SJohn.Forte@Sun.COM 	if (ss_ramcommon_config.ssc_flag & SS_GENPATTERN) {
160*7836SJohn.Forte@Sun.COM 		(void) _sd_fill_pattern(default_cblock,
161*7836SJohn.Forte@Sun.COM 					ss_ramcommon_config.ssc_pattern,
162*7836SJohn.Forte@Sun.COM 					sizeof (default_cblock));
163*7836SJohn.Forte@Sun.COM 	}
164*7836SJohn.Forte@Sun.COM 
165*7836SJohn.Forte@Sun.COM 	ss_ram_config.ss_configured = SS_CONFIGURED;
166*7836SJohn.Forte@Sun.COM 	/* update client */
167*7836SJohn.Forte@Sun.COM 	bcopy(&ss_ramcommon_config, clientptr, sizeof (ss_common_config_t));
168*7836SJohn.Forte@Sun.COM 
169*7836SJohn.Forte@Sun.COM 	mutex_exit(&ss_ram_config_lock);
170*7836SJohn.Forte@Sun.COM 	return (SS_OK);
171*7836SJohn.Forte@Sun.COM }
172*7836SJohn.Forte@Sun.COM 
173*7836SJohn.Forte@Sun.COM /* acquires the ss_ram_config_lock and calls ss_ram_deconfigure_locked() */
174*7836SJohn.Forte@Sun.COM /* ARGSUSED */
175*7836SJohn.Forte@Sun.COM static int
ss_ram_deconfigure(int dirty)176*7836SJohn.Forte@Sun.COM ss_ram_deconfigure(int dirty)
177*7836SJohn.Forte@Sun.COM {
178*7836SJohn.Forte@Sun.COM 	int rc;
179*7836SJohn.Forte@Sun.COM 
180*7836SJohn.Forte@Sun.COM 	if (ss_ram_config.ss_configured != SS_CONFIGURED)
181*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
182*7836SJohn.Forte@Sun.COM 
183*7836SJohn.Forte@Sun.COM 	mutex_enter(&ss_ram_config_lock);
184*7836SJohn.Forte@Sun.COM 	rc = ss_ram_deconfigure_locked();
185*7836SJohn.Forte@Sun.COM 	mutex_exit(&ss_ram_config_lock);
186*7836SJohn.Forte@Sun.COM 
187*7836SJohn.Forte@Sun.COM 	return (rc);
188*7836SJohn.Forte@Sun.COM }
189*7836SJohn.Forte@Sun.COM 
190*7836SJohn.Forte@Sun.COM /*
191*7836SJohn.Forte@Sun.COM  * internal use only
192*7836SJohn.Forte@Sun.COM  * caller should acquire config lock before calling this function
193*7836SJohn.Forte@Sun.COM  */
194*7836SJohn.Forte@Sun.COM static int
ss_ram_deconfigure_locked()195*7836SJohn.Forte@Sun.COM ss_ram_deconfigure_locked()
196*7836SJohn.Forte@Sun.COM {
197*7836SJohn.Forte@Sun.COM 	ss_ram_wctl_deconfigure();
198*7836SJohn.Forte@Sun.COM 	ss_ram_vol_deconfigure();
199*7836SJohn.Forte@Sun.COM 
200*7836SJohn.Forte@Sun.COM 	ss_ram_config.ss_configured = 0;
201*7836SJohn.Forte@Sun.COM 	return (SS_OK);
202*7836SJohn.Forte@Sun.COM }
203*7836SJohn.Forte@Sun.COM 
204*7836SJohn.Forte@Sun.COM static int
ss_ram_getvdir(const ss_vdirkey_t * key,ss_vdir_t * vdir)205*7836SJohn.Forte@Sun.COM ss_ram_getvdir(const ss_vdirkey_t *key, ss_vdir_t *vdir)
206*7836SJohn.Forte@Sun.COM {
207*7836SJohn.Forte@Sun.COM 	ss_ram_vdir_t *ram_vdir = (ss_ram_vdir_t *)vdir;
208*7836SJohn.Forte@Sun.COM 	int rc = SS_OK;
209*7836SJohn.Forte@Sun.COM 
210*7836SJohn.Forte@Sun.COM 	if ((key == NULL) || (vdir == NULL))
211*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
212*7836SJohn.Forte@Sun.COM 
213*7836SJohn.Forte@Sun.COM 	switch (key->vk_type) {
214*7836SJohn.Forte@Sun.COM 		case VDIR_ALL:
215*7836SJohn.Forte@Sun.COM 			ram_vdir->rv_type = VDIR_ALL;
216*7836SJohn.Forte@Sun.COM 			ram_vdir->rv_u.rv_all.rv_current =
217*7836SJohn.Forte@Sun.COM 						ss_ram_config.sn_volumes;
218*7836SJohn.Forte@Sun.COM 			ram_vdir->rv_u.rv_all.rv_end =
219*7836SJohn.Forte@Sun.COM 					ss_ram_config.sn_volumes +
220*7836SJohn.Forte@Sun.COM 					ss_ramcommon_config.ssc_maxfiles;
221*7836SJohn.Forte@Sun.COM 			break;
222*7836SJohn.Forte@Sun.COM 		case VDIR_VOL:
223*7836SJohn.Forte@Sun.COM 		case VDIR_NODE:
224*7836SJohn.Forte@Sun.COM 		default:
225*7836SJohn.Forte@Sun.COM 			rc = SS_ERR;
226*7836SJohn.Forte@Sun.COM 			break;
227*7836SJohn.Forte@Sun.COM 	}
228*7836SJohn.Forte@Sun.COM 
229*7836SJohn.Forte@Sun.COM 	return (rc);
230*7836SJohn.Forte@Sun.COM }
231*7836SJohn.Forte@Sun.COM 
232*7836SJohn.Forte@Sun.COM 
233*7836SJohn.Forte@Sun.COM static int
ss_ram_getvdirent(const ss_vdir_t * vdir,ss_voldata_t * vol)234*7836SJohn.Forte@Sun.COM ss_ram_getvdirent(const ss_vdir_t *vdir, ss_voldata_t *vol)
235*7836SJohn.Forte@Sun.COM {
236*7836SJohn.Forte@Sun.COM 	int rc = SS_OK;
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM 	ss_ram_vdir_t *ram_vdir = (ss_ram_vdir_t *)vdir;
239*7836SJohn.Forte@Sun.COM 
240*7836SJohn.Forte@Sun.COM 	if (vol == NULL)
241*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 	if (vdir == NULL)
244*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
245*7836SJohn.Forte@Sun.COM 
246*7836SJohn.Forte@Sun.COM 	switch (ram_vdir->rv_type) {
247*7836SJohn.Forte@Sun.COM 		case VDIR_ALL:
248*7836SJohn.Forte@Sun.COM 			if (ram_vdir->rv_u.rv_all.rv_current ==
249*7836SJohn.Forte@Sun.COM 					ram_vdir->rv_u.rv_all.rv_end) {
250*7836SJohn.Forte@Sun.COM 				rc = SS_EOF;
251*7836SJohn.Forte@Sun.COM 			} else {
252*7836SJohn.Forte@Sun.COM 				/* stuff client copy with token */
253*7836SJohn.Forte@Sun.COM 				vol->sv_vol = (ss_vol_t *)
254*7836SJohn.Forte@Sun.COM 					ram_vdir->rv_u.rv_all.rv_current++;
255*7836SJohn.Forte@Sun.COM 
256*7836SJohn.Forte@Sun.COM 				/* get the volume data */
257*7836SJohn.Forte@Sun.COM 				rc = ss_ram_getvol(vol);
258*7836SJohn.Forte@Sun.COM 			}
259*7836SJohn.Forte@Sun.COM 			break;
260*7836SJohn.Forte@Sun.COM 		case VDIR_VOL:
261*7836SJohn.Forte@Sun.COM 		case VDIR_NODE:
262*7836SJohn.Forte@Sun.COM 		default:
263*7836SJohn.Forte@Sun.COM 			rc = SS_ERR;
264*7836SJohn.Forte@Sun.COM 			break;
265*7836SJohn.Forte@Sun.COM 	}
266*7836SJohn.Forte@Sun.COM 
267*7836SJohn.Forte@Sun.COM 	return (rc);
268*7836SJohn.Forte@Sun.COM }
269*7836SJohn.Forte@Sun.COM 
270*7836SJohn.Forte@Sun.COM static int
ss_ram_getvol(ss_voldata_t * voldata)271*7836SJohn.Forte@Sun.COM ss_ram_getvol(ss_voldata_t *voldata)
272*7836SJohn.Forte@Sun.COM {
273*7836SJohn.Forte@Sun.COM 	ss_voldata_impl_t *ramvoldata;
274*7836SJohn.Forte@Sun.COM 
275*7836SJohn.Forte@Sun.COM 	if (voldata == NULL)
276*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
277*7836SJohn.Forte@Sun.COM 
278*7836SJohn.Forte@Sun.COM 	/* get the pointer to the volume entry */
279*7836SJohn.Forte@Sun.COM 	ramvoldata = (ss_voldata_impl_t *)voldata->sv_vol;
280*7836SJohn.Forte@Sun.COM 
281*7836SJohn.Forte@Sun.COM 	if (ramvoldata == NULL)
282*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
283*7836SJohn.Forte@Sun.COM 
284*7836SJohn.Forte@Sun.COM 	/* stuff the client structure from the ram entry */
285*7836SJohn.Forte@Sun.COM 	voldata->sv_cd = ramvoldata->svi_cd;
286*7836SJohn.Forte@Sun.COM 	voldata->sv_pinned = ramvoldata->svi_pinned;
287*7836SJohn.Forte@Sun.COM 	voldata->sv_attached = ramvoldata->svi_attached;
288*7836SJohn.Forte@Sun.COM 	voldata->sv_devidsz = ramvoldata->svi_devidsz;
289*7836SJohn.Forte@Sun.COM 
290*7836SJohn.Forte@Sun.COM 	bcopy(ramvoldata->svi_volname, voldata->sv_volname,
291*7836SJohn.Forte@Sun.COM 				sizeof (voldata->sv_volname));
292*7836SJohn.Forte@Sun.COM 
293*7836SJohn.Forte@Sun.COM 	bcopy(ramvoldata->svi_devid, voldata->sv_devid,
294*7836SJohn.Forte@Sun.COM 				sizeof (voldata->sv_devid));
295*7836SJohn.Forte@Sun.COM 	return (SS_OK);
296*7836SJohn.Forte@Sun.COM }
297*7836SJohn.Forte@Sun.COM 
298*7836SJohn.Forte@Sun.COM static int
ss_ram_setvol(const ss_voldata_t * voldata)299*7836SJohn.Forte@Sun.COM ss_ram_setvol(const ss_voldata_t *voldata)
300*7836SJohn.Forte@Sun.COM {
301*7836SJohn.Forte@Sun.COM 	ss_voldata_impl_t *ramvoldata;
302*7836SJohn.Forte@Sun.COM 
303*7836SJohn.Forte@Sun.COM 	if (voldata == NULL)
304*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
305*7836SJohn.Forte@Sun.COM 
306*7836SJohn.Forte@Sun.COM 	/* get the pointer to the volume entry */
307*7836SJohn.Forte@Sun.COM 	ramvoldata = (ss_voldata_impl_t *)voldata->sv_vol;
308*7836SJohn.Forte@Sun.COM 
309*7836SJohn.Forte@Sun.COM 	if (ramvoldata == NULL)
310*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
311*7836SJohn.Forte@Sun.COM 
312*7836SJohn.Forte@Sun.COM 	/* load the volume entry from the client structure */
313*7836SJohn.Forte@Sun.COM 	ramvoldata->svi_cd = voldata->sv_cd;
314*7836SJohn.Forte@Sun.COM 	ramvoldata->svi_pinned = voldata->sv_pinned;
315*7836SJohn.Forte@Sun.COM 	ramvoldata->svi_attached = voldata->sv_attached;
316*7836SJohn.Forte@Sun.COM 	ramvoldata->svi_devidsz = voldata->sv_devidsz;
317*7836SJohn.Forte@Sun.COM 	bcopy(voldata->sv_volname, ramvoldata->svi_volname,
318*7836SJohn.Forte@Sun.COM 				sizeof (ramvoldata->svi_volname));
319*7836SJohn.Forte@Sun.COM 
320*7836SJohn.Forte@Sun.COM 	bcopy(voldata->sv_devid, ramvoldata->svi_devid,
321*7836SJohn.Forte@Sun.COM 				sizeof (ramvoldata->svi_devid));
322*7836SJohn.Forte@Sun.COM 	return (SS_OK);
323*7836SJohn.Forte@Sun.COM }
324*7836SJohn.Forte@Sun.COM 
325*7836SJohn.Forte@Sun.COM static int
ss_ram_getcdir(const ss_cdirkey_t * key,ss_cdir_t * cdir)326*7836SJohn.Forte@Sun.COM ss_ram_getcdir(const ss_cdirkey_t *key, ss_cdir_t *cdir)
327*7836SJohn.Forte@Sun.COM {
328*7836SJohn.Forte@Sun.COM 	ss_ram_cdir_t *ram_cdir = (ss_ram_cdir_t *)cdir;
329*7836SJohn.Forte@Sun.COM 	int rc = 0;
330*7836SJohn.Forte@Sun.COM 
331*7836SJohn.Forte@Sun.COM 	if ((key == NULL) || (cdir == NULL))
332*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
333*7836SJohn.Forte@Sun.COM 
334*7836SJohn.Forte@Sun.COM 	switch (key->ck_type) {
335*7836SJohn.Forte@Sun.COM 		case CDIR_ALL:
336*7836SJohn.Forte@Sun.COM 			{ int blocks;
337*7836SJohn.Forte@Sun.COM 
338*7836SJohn.Forte@Sun.COM 				blocks = ss_ramcommon_config.ssc_wsize /
339*7836SJohn.Forte@Sun.COM 					ss_ramcommon_config.ssc_client_psize;
340*7836SJohn.Forte@Sun.COM 
341*7836SJohn.Forte@Sun.COM 				ram_cdir->rc_type = CDIR_ALL;
342*7836SJohn.Forte@Sun.COM 				ram_cdir->rc_u.rc_all.rc_current =
343*7836SJohn.Forte@Sun.COM 						ss_ram_config.sn_wr_cctl;
344*7836SJohn.Forte@Sun.COM 				ram_cdir->rc_u.rc_all.rc_end =
345*7836SJohn.Forte@Sun.COM 					ss_ram_config.sn_wr_cctl + blocks;
346*7836SJohn.Forte@Sun.COM 			}
347*7836SJohn.Forte@Sun.COM 			break;
348*7836SJohn.Forte@Sun.COM 		case CDIR_VOL:
349*7836SJohn.Forte@Sun.COM 		case CDIR_NODE:
350*7836SJohn.Forte@Sun.COM 		default:
351*7836SJohn.Forte@Sun.COM 			rc = SS_ERR;
352*7836SJohn.Forte@Sun.COM 			break;
353*7836SJohn.Forte@Sun.COM 	}
354*7836SJohn.Forte@Sun.COM 
355*7836SJohn.Forte@Sun.COM 	return (rc);
356*7836SJohn.Forte@Sun.COM }
357*7836SJohn.Forte@Sun.COM 
358*7836SJohn.Forte@Sun.COM static int
ss_ram_getcdirent(ss_cdir_t * cdir,ss_centry_info_t * centry)359*7836SJohn.Forte@Sun.COM ss_ram_getcdirent(ss_cdir_t *cdir, ss_centry_info_t *centry)
360*7836SJohn.Forte@Sun.COM {
361*7836SJohn.Forte@Sun.COM 	int rc = SS_OK;
362*7836SJohn.Forte@Sun.COM 
363*7836SJohn.Forte@Sun.COM 	ss_ram_cdir_t *ram_cdir = (ss_ram_cdir_t *)cdir;
364*7836SJohn.Forte@Sun.COM 
365*7836SJohn.Forte@Sun.COM 	if (centry == NULL)
366*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
367*7836SJohn.Forte@Sun.COM 
368*7836SJohn.Forte@Sun.COM 	if (cdir == NULL)
369*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
370*7836SJohn.Forte@Sun.COM 
371*7836SJohn.Forte@Sun.COM 	switch (ram_cdir->rc_type) {
372*7836SJohn.Forte@Sun.COM 		case CDIR_ALL:
373*7836SJohn.Forte@Sun.COM 			if (ram_cdir->rc_u.rc_all.rc_current ==
374*7836SJohn.Forte@Sun.COM 						ram_cdir->rc_u.rc_all.rc_end) {
375*7836SJohn.Forte@Sun.COM 				rc = SS_EOF;
376*7836SJohn.Forte@Sun.COM 			} else {
377*7836SJohn.Forte@Sun.COM 				/* stuff client copy with token */
378*7836SJohn.Forte@Sun.COM 				centry->sc_res = (ss_resource_t *)
379*7836SJohn.Forte@Sun.COM 					ram_cdir->rc_u.rc_all.rc_current++;
380*7836SJohn.Forte@Sun.COM 
381*7836SJohn.Forte@Sun.COM 				/* get the centry data */
382*7836SJohn.Forte@Sun.COM 				rc = ss_ram_getcentry(centry);
383*7836SJohn.Forte@Sun.COM 			}
384*7836SJohn.Forte@Sun.COM 			break;
385*7836SJohn.Forte@Sun.COM 		case CDIR_VOL:
386*7836SJohn.Forte@Sun.COM 		case CDIR_NODE:
387*7836SJohn.Forte@Sun.COM 		default:
388*7836SJohn.Forte@Sun.COM 			rc = SS_ERR;
389*7836SJohn.Forte@Sun.COM 			break;
390*7836SJohn.Forte@Sun.COM 	}
391*7836SJohn.Forte@Sun.COM 
392*7836SJohn.Forte@Sun.COM 	return (rc);
393*7836SJohn.Forte@Sun.COM }
394*7836SJohn.Forte@Sun.COM 
395*7836SJohn.Forte@Sun.COM static int
ss_ram_allocresource(int need,int * stall,ss_resourcelist_t ** reslist)396*7836SJohn.Forte@Sun.COM ss_ram_allocresource(int need, int *stall, ss_resourcelist_t **reslist)
397*7836SJohn.Forte@Sun.COM {
398*7836SJohn.Forte@Sun.COM 	if (reslist == NULL)
399*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
400*7836SJohn.Forte@Sun.COM 
401*7836SJohn.Forte@Sun.COM 	*reslist = ((ss_resourcelist_t *)ss_alloc_write(need, stall,
402*7836SJohn.Forte@Sun.COM 					&(ss_ram_config.sn_wr_queue)));
403*7836SJohn.Forte@Sun.COM 	if (*reslist == NULL)    /* do sync write */
404*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
405*7836SJohn.Forte@Sun.COM 
406*7836SJohn.Forte@Sun.COM 	return (SS_OK);
407*7836SJohn.Forte@Sun.COM }
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM static void
ss_ram_deallocresource(ss_resource_t * res)410*7836SJohn.Forte@Sun.COM ss_ram_deallocresource(ss_resource_t *res)
411*7836SJohn.Forte@Sun.COM {
412*7836SJohn.Forte@Sun.COM 	ss_release_write((ss_wr_cctl_t *)res, &(ss_ram_config.sn_wr_queue));
413*7836SJohn.Forte@Sun.COM }
414*7836SJohn.Forte@Sun.COM 
415*7836SJohn.Forte@Sun.COM static int
ss_ram_getresource(ss_resourcelist_t ** reslist,ss_resource_t ** res)416*7836SJohn.Forte@Sun.COM ss_ram_getresource(ss_resourcelist_t **reslist, ss_resource_t **res)
417*7836SJohn.Forte@Sun.COM {
418*7836SJohn.Forte@Sun.COM 	if ((res == NULL) || (reslist == NULL)) {
419*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
420*7836SJohn.Forte@Sun.COM 	}
421*7836SJohn.Forte@Sun.COM 
422*7836SJohn.Forte@Sun.COM 	if (*reslist == NULL)
423*7836SJohn.Forte@Sun.COM 		return (SS_EOF);
424*7836SJohn.Forte@Sun.COM 
425*7836SJohn.Forte@Sun.COM 	*res = (ss_resource_t *)(*reslist);
426*7836SJohn.Forte@Sun.COM 	*reslist = (ss_resourcelist_t *)
427*7836SJohn.Forte@Sun.COM 		((ss_wr_cctl_t *)(*reslist))->wc_next;
428*7836SJohn.Forte@Sun.COM 
429*7836SJohn.Forte@Sun.COM 	return (SS_OK);
430*7836SJohn.Forte@Sun.COM }
431*7836SJohn.Forte@Sun.COM 
432*7836SJohn.Forte@Sun.COM static int
ss_ram_getcentry(ss_centry_info_t * centry)433*7836SJohn.Forte@Sun.COM ss_ram_getcentry(ss_centry_info_t *centry)
434*7836SJohn.Forte@Sun.COM {
435*7836SJohn.Forte@Sun.COM 	ss_wr_cctl_t *wctl;
436*7836SJohn.Forte@Sun.COM 	ss_centry_info_impl_t *ramcentry = (ss_centry_info_impl_t *)centry;
437*7836SJohn.Forte@Sun.COM 
438*7836SJohn.Forte@Sun.COM 	if (centry == NULL)
439*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
440*7836SJohn.Forte@Sun.COM 	else
441*7836SJohn.Forte@Sun.COM 		wctl = (ss_wr_cctl_t *)centry->sc_res;
442*7836SJohn.Forte@Sun.COM 
443*7836SJohn.Forte@Sun.COM 	if (wctl == NULL)
444*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
445*7836SJohn.Forte@Sun.COM 
446*7836SJohn.Forte@Sun.COM 	if (wctl->wc_gl_info)
447*7836SJohn.Forte@Sun.COM 		bcopy(wctl->wc_gl_info, ramcentry,
448*7836SJohn.Forte@Sun.COM 			sizeof (ss_centry_info_impl_t));
449*7836SJohn.Forte@Sun.COM 	else
450*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
451*7836SJohn.Forte@Sun.COM 
452*7836SJohn.Forte@Sun.COM 	return (SS_OK);
453*7836SJohn.Forte@Sun.COM }
454*7836SJohn.Forte@Sun.COM 
455*7836SJohn.Forte@Sun.COM static int
ss_ram_setcentry(const ss_centry_info_t * centry)456*7836SJohn.Forte@Sun.COM ss_ram_setcentry(const ss_centry_info_t *centry)
457*7836SJohn.Forte@Sun.COM {
458*7836SJohn.Forte@Sun.COM 	ss_wr_cctl_t *wctl;
459*7836SJohn.Forte@Sun.COM 	ss_centry_info_impl_t *ramcentry = (ss_centry_info_impl_t *)centry;
460*7836SJohn.Forte@Sun.COM 
461*7836SJohn.Forte@Sun.COM 	if (centry == NULL)
462*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
463*7836SJohn.Forte@Sun.COM 	else
464*7836SJohn.Forte@Sun.COM 		wctl = (ss_wr_cctl_t *)centry->sc_res;
465*7836SJohn.Forte@Sun.COM 
466*7836SJohn.Forte@Sun.COM 	if (wctl == NULL)
467*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
468*7836SJohn.Forte@Sun.COM 
469*7836SJohn.Forte@Sun.COM 	if (wctl->wc_gl_info)
470*7836SJohn.Forte@Sun.COM 		bcopy(ramcentry, wctl->wc_gl_info,
471*7836SJohn.Forte@Sun.COM 				sizeof (ss_centry_info_impl_t));
472*7836SJohn.Forte@Sun.COM 	else
473*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
474*7836SJohn.Forte@Sun.COM 
475*7836SJohn.Forte@Sun.COM 	return (SS_OK);
476*7836SJohn.Forte@Sun.COM }
477*7836SJohn.Forte@Sun.COM 
478*7836SJohn.Forte@Sun.COM 
479*7836SJohn.Forte@Sun.COM static int
ss_ram_cblock_read(const ss_resource_t * res,void * buf,int count,int srcoffset)480*7836SJohn.Forte@Sun.COM ss_ram_cblock_read(const ss_resource_t *res, void *buf,
481*7836SJohn.Forte@Sun.COM 				int count, int srcoffset)
482*7836SJohn.Forte@Sun.COM {
483*7836SJohn.Forte@Sun.COM 	if ((res == NULL) || (buf == NULL))
484*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
485*7836SJohn.Forte@Sun.COM 
486*7836SJohn.Forte@Sun.COM 	if ((srcoffset < 0) ||
487*7836SJohn.Forte@Sun.COM 			(srcoffset > ss_ramcommon_config.ssc_client_psize))
488*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
489*7836SJohn.Forte@Sun.COM 
490*7836SJohn.Forte@Sun.COM 	bcopy(default_cblock + srcoffset, buf, count);
491*7836SJohn.Forte@Sun.COM 
492*7836SJohn.Forte@Sun.COM 	return (SS_OK);
493*7836SJohn.Forte@Sun.COM }
494*7836SJohn.Forte@Sun.COM 
495*7836SJohn.Forte@Sun.COM static int
ss_ram_cblock_write(const ss_resource_t * res,const void * buf,int count,int destoffset)496*7836SJohn.Forte@Sun.COM ss_ram_cblock_write(const ss_resource_t *res,
497*7836SJohn.Forte@Sun.COM 			const void *buf, int count, int destoffset)
498*7836SJohn.Forte@Sun.COM {
499*7836SJohn.Forte@Sun.COM 	if ((res == NULL) || (buf == NULL))
500*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
501*7836SJohn.Forte@Sun.COM 
502*7836SJohn.Forte@Sun.COM 	if ((destoffset < 0) ||
503*7836SJohn.Forte@Sun.COM 			(destoffset > ss_ramcommon_config.ssc_client_psize))
504*7836SJohn.Forte@Sun.COM 		return (SS_ERR);
505*7836SJohn.Forte@Sun.COM 
506*7836SJohn.Forte@Sun.COM 	bcopy(buf, default_cblock + destoffset, count);
507*7836SJohn.Forte@Sun.COM 
508*7836SJohn.Forte@Sun.COM 	return (SS_OK);
509*7836SJohn.Forte@Sun.COM }
510*7836SJohn.Forte@Sun.COM 
511*7836SJohn.Forte@Sun.COM static int
ss_ram_ctl(uint_t cmd,uintptr_t arg)512*7836SJohn.Forte@Sun.COM ss_ram_ctl(uint_t cmd, uintptr_t arg)
513*7836SJohn.Forte@Sun.COM {
514*7836SJohn.Forte@Sun.COM 	int rc = SS_OK;
515*7836SJohn.Forte@Sun.COM 
516*7836SJohn.Forte@Sun.COM 	switch (cmd) {
517*7836SJohn.Forte@Sun.COM 		case SSIOC_STATS:
518*7836SJohn.Forte@Sun.COM 			((ssioc_stats_t *)arg)->wq_inq =
519*7836SJohn.Forte@Sun.COM 					ss_ram_config.sn_wr_queue.wq_inq;
520*7836SJohn.Forte@Sun.COM 			break;
521*7836SJohn.Forte@Sun.COM 		default:
522*7836SJohn.Forte@Sun.COM 			cmn_err(CE_WARN, "ss_nvs_ctl: cmd %x not supported",
523*7836SJohn.Forte@Sun.COM 							cmd);
524*7836SJohn.Forte@Sun.COM 			rc = ENOTTY;
525*7836SJohn.Forte@Sun.COM 			break;
526*7836SJohn.Forte@Sun.COM 	}
527*7836SJohn.Forte@Sun.COM 
528*7836SJohn.Forte@Sun.COM 	return (rc);
529*7836SJohn.Forte@Sun.COM }
530*7836SJohn.Forte@Sun.COM 
531*7836SJohn.Forte@Sun.COM static int
ss_ram_vol_configure(int maxvols)532*7836SJohn.Forte@Sun.COM ss_ram_vol_configure(int maxvols)
533*7836SJohn.Forte@Sun.COM {
534*7836SJohn.Forte@Sun.COM 	if ((ss_ram_config.sn_volumes = kmem_zalloc(maxvols *
535*7836SJohn.Forte@Sun.COM 			sizeof (ss_voldata_impl_t), KM_NOSLEEP)) == NULL)
536*7836SJohn.Forte@Sun.COM 		return (-1);
537*7836SJohn.Forte@Sun.COM 
538*7836SJohn.Forte@Sun.COM 	return (0);
539*7836SJohn.Forte@Sun.COM }
540*7836SJohn.Forte@Sun.COM 
541*7836SJohn.Forte@Sun.COM static void
ss_ram_vol_deconfigure()542*7836SJohn.Forte@Sun.COM ss_ram_vol_deconfigure()
543*7836SJohn.Forte@Sun.COM {
544*7836SJohn.Forte@Sun.COM 	int maxvols = ss_ramcommon_config.ssc_maxfiles;
545*7836SJohn.Forte@Sun.COM 
546*7836SJohn.Forte@Sun.COM 	if (ss_ram_config.sn_volumes)
547*7836SJohn.Forte@Sun.COM 		kmem_free(ss_ram_config.sn_volumes,
548*7836SJohn.Forte@Sun.COM 					maxvols * sizeof (ss_voldata_impl_t));
549*7836SJohn.Forte@Sun.COM }
550*7836SJohn.Forte@Sun.COM 
551*7836SJohn.Forte@Sun.COM static int
ss_ram_wctl_configure()552*7836SJohn.Forte@Sun.COM ss_ram_wctl_configure()
553*7836SJohn.Forte@Sun.COM {
554*7836SJohn.Forte@Sun.COM 	int blocks;
555*7836SJohn.Forte@Sun.COM 	ss_wr_cctl_t *wentry;
556*7836SJohn.Forte@Sun.COM 	static ss_centry_info_impl_t *gl;
557*7836SJohn.Forte@Sun.COM 	int i;
558*7836SJohn.Forte@Sun.COM 
559*7836SJohn.Forte@Sun.COM 	blocks = ss_ramcommon_config.ssc_wsize /
560*7836SJohn.Forte@Sun.COM 			ss_ramcommon_config.ssc_client_psize;
561*7836SJohn.Forte@Sun.COM 
562*7836SJohn.Forte@Sun.COM 	if ((ss_ram_config.sn_wr_cctl = (ss_wr_cctl_t *)
563*7836SJohn.Forte@Sun.COM 		kmem_zalloc(blocks * sizeof (ss_wr_cctl_t), KM_NOSLEEP))
564*7836SJohn.Forte@Sun.COM 								== NULL) {
565*7836SJohn.Forte@Sun.COM 		return (-1);
566*7836SJohn.Forte@Sun.COM 	}
567*7836SJohn.Forte@Sun.COM 
568*7836SJohn.Forte@Sun.COM 	if ((ss_ram_config.sn_gl_centry_info = (ss_centry_info_impl_t *)
569*7836SJohn.Forte@Sun.COM 		kmem_zalloc(blocks * sizeof (ss_centry_info_impl_t),
570*7836SJohn.Forte@Sun.COM 					KM_NOSLEEP)) == NULL) {
571*7836SJohn.Forte@Sun.COM 		return (-1);
572*7836SJohn.Forte@Sun.COM 	}
573*7836SJohn.Forte@Sun.COM 
574*7836SJohn.Forte@Sun.COM 	/*
575*7836SJohn.Forte@Sun.COM 	 * Mini-DSP: no write/ft area
576*7836SJohn.Forte@Sun.COM 	 * (ie forced_wrthru clear)
577*7836SJohn.Forte@Sun.COM 	 */
578*7836SJohn.Forte@Sun.COM 
579*7836SJohn.Forte@Sun.COM 	if (_sdbc_writeq_configure(&(ss_ram_config.sn_wr_queue)) != 0)
580*7836SJohn.Forte@Sun.COM 		return (-1);
581*7836SJohn.Forte@Sun.COM 
582*7836SJohn.Forte@Sun.COM 	gl = ss_ram_config.sn_gl_centry_info;
583*7836SJohn.Forte@Sun.COM 
584*7836SJohn.Forte@Sun.COM 	wentry = ss_ram_config.sn_wr_cctl;
585*7836SJohn.Forte@Sun.COM 	for (i = 0; i < blocks; ++i, ++wentry) {
586*7836SJohn.Forte@Sun.COM 		wentry->wc_gl_info = gl++;
587*7836SJohn.Forte@Sun.COM 		ss_release_write(wentry, &(ss_ram_config.sn_wr_queue));
588*7836SJohn.Forte@Sun.COM 	}
589*7836SJohn.Forte@Sun.COM 
590*7836SJohn.Forte@Sun.COM 	ss_ram_config.sn_wr_queue.wq_nentries = blocks;
591*7836SJohn.Forte@Sun.COM 
592*7836SJohn.Forte@Sun.COM 	return (0);
593*7836SJohn.Forte@Sun.COM }
594*7836SJohn.Forte@Sun.COM 
595*7836SJohn.Forte@Sun.COM static void
ss_ram_wctl_deconfigure()596*7836SJohn.Forte@Sun.COM ss_ram_wctl_deconfigure()
597*7836SJohn.Forte@Sun.COM {
598*7836SJohn.Forte@Sun.COM 	int blocks;
599*7836SJohn.Forte@Sun.COM 
600*7836SJohn.Forte@Sun.COM 	_sdbc_writeq_deconfigure(&(ss_ram_config.sn_wr_queue));
601*7836SJohn.Forte@Sun.COM 
602*7836SJohn.Forte@Sun.COM 	blocks = ss_ramcommon_config.ssc_wsize /
603*7836SJohn.Forte@Sun.COM 			ss_ramcommon_config.ssc_client_psize;
604*7836SJohn.Forte@Sun.COM 
605*7836SJohn.Forte@Sun.COM 	if (ss_ram_config.sn_wr_cctl) {
606*7836SJohn.Forte@Sun.COM 		kmem_free(ss_ram_config.sn_wr_cctl,
607*7836SJohn.Forte@Sun.COM 				blocks * sizeof (ss_wr_cctl_t));
608*7836SJohn.Forte@Sun.COM 	}
609*7836SJohn.Forte@Sun.COM 
610*7836SJohn.Forte@Sun.COM 	if (ss_ram_config.sn_gl_centry_info) {
611*7836SJohn.Forte@Sun.COM 		kmem_free(ss_ram_config.sn_gl_centry_info,
612*7836SJohn.Forte@Sun.COM 				blocks * sizeof (ss_centry_info_impl_t));
613*7836SJohn.Forte@Sun.COM 	}
614*7836SJohn.Forte@Sun.COM }
615