17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*9093SRamana.Srikanth@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM #include <sys/types.h>
277836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
287836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
297836SJohn.Forte@Sun.COM #include <sys/errno.h>
307836SJohn.Forte@Sun.COM #include <sys/kmem.h>
317836SJohn.Forte@Sun.COM #include <sys/ddi.h>
327836SJohn.Forte@Sun.COM
337836SJohn.Forte@Sun.COM #include <sys/nsc_thread.h>
347836SJohn.Forte@Sun.COM #include "sd_bcache.h"
357836SJohn.Forte@Sun.COM #include "sd_ft.h"
367836SJohn.Forte@Sun.COM #include "sd_misc.h"
377836SJohn.Forte@Sun.COM #include "sd_pcu.h"
387836SJohn.Forte@Sun.COM #include "sd_io.h"
397836SJohn.Forte@Sun.COM #include "sd_bio.h"
407836SJohn.Forte@Sun.COM #include "sd_trace.h"
417836SJohn.Forte@Sun.COM #include "sd_tdaemon.h"
427836SJohn.Forte@Sun.COM #include <sys/nsctl/nsctl.h>
437836SJohn.Forte@Sun.COM
447836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
457836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_k.h>
467836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
477836SJohn.Forte@Sun.COM #include <sys/nsctl/safestore.h>
487836SJohn.Forte@Sun.COM
497836SJohn.Forte@Sun.COM extern int sdbc_use_dmchain;
507836SJohn.Forte@Sun.COM
517836SJohn.Forte@Sun.COM int _sd_cblock_shift = 0;
527836SJohn.Forte@Sun.COM
537836SJohn.Forte@Sun.COM int _SD_SELF_HOST = _SD_NO_HOST;
547836SJohn.Forte@Sun.COM int _SD_MIRROR_HOST = _SD_NO_HOST;
557836SJohn.Forte@Sun.COM int _SD_NUM_REM;
567836SJohn.Forte@Sun.COM int _sd_nodes_configured;
577836SJohn.Forte@Sun.COM int _sdbc_gateway_wblocks;
587836SJohn.Forte@Sun.COM
597836SJohn.Forte@Sun.COM int _SD_NETS = 0;
607836SJohn.Forte@Sun.COM
617836SJohn.Forte@Sun.COM /*
627836SJohn.Forte@Sun.COM * Normally we unregister memory at deconfig time. By setting this non-zero
637836SJohn.Forte@Sun.COM * it will be delayed until unload time.
647836SJohn.Forte@Sun.COM */
657836SJohn.Forte@Sun.COM int _sdbc_memtype_deconfigure_delayed = 0;
667836SJohn.Forte@Sun.COM
677836SJohn.Forte@Sun.COM nsc_mem_t *sdbc_iobuf_mem, *sdbc_hash_mem;
687836SJohn.Forte@Sun.COM nsc_mem_t *sdbc_local_mem, *sdbc_stats_mem, *sdbc_cache_mem;
697836SJohn.Forte@Sun.COM nsc_mem_t *sdbc_info_mem;
707836SJohn.Forte@Sun.COM
717836SJohn.Forte@Sun.COM _sd_cache_param_t _sd_cache_config;
727836SJohn.Forte@Sun.COM
737836SJohn.Forte@Sun.COM kmutex_t _sdbc_config_lock;
747836SJohn.Forte@Sun.COM volatile int _sd_cache_dem_cnt;
757836SJohn.Forte@Sun.COM
767836SJohn.Forte@Sun.COM #if !defined(m88k) || defined(lint)
777836SJohn.Forte@Sun.COM volatile int _sd_cache_initialized;
787836SJohn.Forte@Sun.COM #endif
797836SJohn.Forte@Sun.COM
807836SJohn.Forte@Sun.COM static blind_t sdbc_power;
817836SJohn.Forte@Sun.COM
827836SJohn.Forte@Sun.COM static
837836SJohn.Forte@Sun.COM nsc_def_t _sdbc_power_def[] = {
847836SJohn.Forte@Sun.COM "Power_Lost", (uintptr_t)_sdbc_power_lost, 0,
857836SJohn.Forte@Sun.COM "Power_OK", (uintptr_t)_sdbc_power_ok, 0,
867836SJohn.Forte@Sun.COM "Power_Down", (uintptr_t)_sdbc_power_down, 0,
877836SJohn.Forte@Sun.COM 0, 0, 0
887836SJohn.Forte@Sun.COM };
897836SJohn.Forte@Sun.COM
907836SJohn.Forte@Sun.COM /*
917836SJohn.Forte@Sun.COM * Forward declare all statics that are used before defined to enforce
927836SJohn.Forte@Sun.COM * parameter checking
937836SJohn.Forte@Sun.COM * Some (if not all) of these could be removed if the code were reordered
947836SJohn.Forte@Sun.COM */
957836SJohn.Forte@Sun.COM
967836SJohn.Forte@Sun.COM int _sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size);
977836SJohn.Forte@Sun.COM static void _sdbc_nodeid_deconfigure(void);
987836SJohn.Forte@Sun.COM static void _sdbc_nodeid_configure(void);
997836SJohn.Forte@Sun.COM static void _sdbc_thread_deconfigure(void);
1007836SJohn.Forte@Sun.COM static int _sdbc_thread_configure(void);
1017836SJohn.Forte@Sun.COM void sst_deinit();
1027836SJohn.Forte@Sun.COM
1037836SJohn.Forte@Sun.COM ss_common_config_t safestore_config;
1047836SJohn.Forte@Sun.COM safestore_ops_t *sdbc_safestore;
1057836SJohn.Forte@Sun.COM
1067836SJohn.Forte@Sun.COM /*
1077836SJohn.Forte@Sun.COM * _sdbc_memtype_configure - register with the sd layer the types of memory
1087836SJohn.Forte@Sun.COM * we want to use. If any of the critical memory types can't be registered
1097836SJohn.Forte@Sun.COM * we return non-zero otherwise 0.
1107836SJohn.Forte@Sun.COM */
1117836SJohn.Forte@Sun.COM static int
_sdbc_memtype_configure(void)1127836SJohn.Forte@Sun.COM _sdbc_memtype_configure(void)
1137836SJohn.Forte@Sun.COM {
1147836SJohn.Forte@Sun.COM
1157836SJohn.Forte@Sun.COM if ((sdbc_info_mem = nsc_register_mem("sdbc:info",
1167836SJohn.Forte@Sun.COM NSC_MEM_GLOBAL, KM_NOSLEEP)) == NULL) {
1177836SJohn.Forte@Sun.COM return (EINVAL);
1187836SJohn.Forte@Sun.COM }
1197836SJohn.Forte@Sun.COM
1207836SJohn.Forte@Sun.COM sdbc_local_mem = nsc_register_mem("sdbc:local", NSC_MEM_LOCAL, 0);
1217836SJohn.Forte@Sun.COM sdbc_stats_mem = nsc_register_mem("sdbc:stats", NSC_MEM_LOCAL, 0);
1227836SJohn.Forte@Sun.COM sdbc_iobuf_mem = nsc_register_mem("sdbc:iobuf", NSC_MEM_LOCAL, 0);
1237836SJohn.Forte@Sun.COM
1247836SJohn.Forte@Sun.COM sdbc_cache_mem = nsc_register_mem("sdbc:cache", NSC_MEM_LOCAL, 0);
1257836SJohn.Forte@Sun.COM
1267836SJohn.Forte@Sun.COM sdbc_hash_mem = nsc_register_mem("sdbc:hash", NSC_MEM_LOCAL, 0);
1277836SJohn.Forte@Sun.COM
1287836SJohn.Forte@Sun.COM return (0);
1297836SJohn.Forte@Sun.COM }
1307836SJohn.Forte@Sun.COM
1317836SJohn.Forte@Sun.COM /*
1327836SJohn.Forte@Sun.COM * _sdbc_memtype_deconfigure - undo the effects of _sdbc_memtype_configure.
1337836SJohn.Forte@Sun.COM */
1347836SJohn.Forte@Sun.COM void
_sdbc_memtype_deconfigure(void)1357836SJohn.Forte@Sun.COM _sdbc_memtype_deconfigure(void)
1367836SJohn.Forte@Sun.COM {
1377836SJohn.Forte@Sun.COM
1387836SJohn.Forte@Sun.COM if (sdbc_hash_mem)
1397836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_hash_mem);
1407836SJohn.Forte@Sun.COM if (sdbc_iobuf_mem)
1417836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_iobuf_mem);
1427836SJohn.Forte@Sun.COM if (sdbc_cache_mem)
1437836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_cache_mem);
1447836SJohn.Forte@Sun.COM if (sdbc_stats_mem)
1457836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_stats_mem);
1467836SJohn.Forte@Sun.COM if (sdbc_local_mem)
1477836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_local_mem);
1487836SJohn.Forte@Sun.COM if (sdbc_info_mem)
1497836SJohn.Forte@Sun.COM nsc_unregister_mem(sdbc_info_mem);
1507836SJohn.Forte@Sun.COM
1517836SJohn.Forte@Sun.COM sdbc_info_mem = NULL;
1527836SJohn.Forte@Sun.COM sdbc_local_mem = sdbc_stats_mem = sdbc_cache_mem = NULL;
1537836SJohn.Forte@Sun.COM sdbc_iobuf_mem = sdbc_hash_mem = NULL;
1547836SJohn.Forte@Sun.COM
1557836SJohn.Forte@Sun.COM }
1567836SJohn.Forte@Sun.COM
1577836SJohn.Forte@Sun.COM
1587836SJohn.Forte@Sun.COM /*
1597836SJohn.Forte@Sun.COM * figure out what kind of safe storage we need
1607836SJohn.Forte@Sun.COM */
1617836SJohn.Forte@Sun.COM uint_t
sdbc_determine_safestore()1627836SJohn.Forte@Sun.COM sdbc_determine_safestore()
1637836SJohn.Forte@Sun.COM {
1647836SJohn.Forte@Sun.COM return (SS_M_RAM | SS_T_NONE);
1657836SJohn.Forte@Sun.COM }
1667836SJohn.Forte@Sun.COM
1677836SJohn.Forte@Sun.COM static void
sd_setup_ssconfig()1687836SJohn.Forte@Sun.COM sd_setup_ssconfig()
1697836SJohn.Forte@Sun.COM {
1707836SJohn.Forte@Sun.COM safestore_config.ssc_client_psize = BLK_SIZE(1);
1717836SJohn.Forte@Sun.COM
1727836SJohn.Forte@Sun.COM if (_sd_cache_config.write_cache)
1737836SJohn.Forte@Sun.COM safestore_config.ssc_wsize =
174*9093SRamana.Srikanth@Sun.COM _sd_cache_config.write_cache * MEGABYTE;
1757836SJohn.Forte@Sun.COM else
1767836SJohn.Forte@Sun.COM safestore_config.ssc_wsize =
177*9093SRamana.Srikanth@Sun.COM (_sd_cache_config.cache_mem[_SD_NO_NET] * MEGABYTE)/2;
1787836SJohn.Forte@Sun.COM safestore_config.ssc_maxfiles = sdbc_max_devs;
1797836SJohn.Forte@Sun.COM safestore_config.ssc_pattern = _sd_cache_config.fill_pattern;
1807836SJohn.Forte@Sun.COM safestore_config.ssc_flag = _sd_cache_config.gen_pattern ?
1817836SJohn.Forte@Sun.COM SS_GENPATTERN : 0;
1827836SJohn.Forte@Sun.COM }
1837836SJohn.Forte@Sun.COM
1847836SJohn.Forte@Sun.COM /*
1857836SJohn.Forte@Sun.COM * _sdbc_configure - process the ioctl that describes the configuration
1867836SJohn.Forte@Sun.COM * for the cache. This is the main driver routine for cache configuration
1877836SJohn.Forte@Sun.COM * Return 0 on success, otherwise nonzero.
1887836SJohn.Forte@Sun.COM *
1897836SJohn.Forte@Sun.COM */
1907836SJohn.Forte@Sun.COM int
_sdbc_configure(_sd_cache_param_t * uptr,_sdbc_config_t * mgmt,spcs_s_info_t spcs_kstatus)1917836SJohn.Forte@Sun.COM _sdbc_configure(_sd_cache_param_t *uptr,
1927836SJohn.Forte@Sun.COM _sdbc_config_t *mgmt, spcs_s_info_t spcs_kstatus)
1937836SJohn.Forte@Sun.COM {
1947836SJohn.Forte@Sun.COM int cache_bytes;
1957836SJohn.Forte@Sun.COM nsc_io_t *io;
1967836SJohn.Forte@Sun.COM char itmp[16];
1977836SJohn.Forte@Sun.COM char itmp2[16];
1987836SJohn.Forte@Sun.COM int i;
1997836SJohn.Forte@Sun.COM uint_t ss_type;
2007836SJohn.Forte@Sun.COM int rc;
2017836SJohn.Forte@Sun.COM
2027836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&_sdbc_config_lock));
2037836SJohn.Forte@Sun.COM
2047836SJohn.Forte@Sun.COM _sd_print(1, "sdbc(_sdbc_configure) _SD_MAGIC 0x%x\n", _SD_MAGIC);
2057836SJohn.Forte@Sun.COM
2067836SJohn.Forte@Sun.COM _sd_ioset = 0;
2077836SJohn.Forte@Sun.COM if (_sd_cache_initialized) {
2087836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_EALREADY);
2097836SJohn.Forte@Sun.COM rc = EALREADY;
2107836SJohn.Forte@Sun.COM goto out;
2117836SJohn.Forte@Sun.COM }
2127836SJohn.Forte@Sun.COM
2137836SJohn.Forte@Sun.COM ASSERT((uptr != NULL) || (mgmt != NULL));
2147836SJohn.Forte@Sun.COM
2157836SJohn.Forte@Sun.COM if (uptr) {
2167836SJohn.Forte@Sun.COM if (copyin(uptr, &_sd_cache_config,
2177836SJohn.Forte@Sun.COM sizeof (_sd_cache_param_t))) {
2187836SJohn.Forte@Sun.COM rc = EFAULT;
2197836SJohn.Forte@Sun.COM goto out;
2207836SJohn.Forte@Sun.COM }
2217836SJohn.Forte@Sun.COM } else {
2227836SJohn.Forte@Sun.COM bzero(&_sd_cache_config, sizeof (_sd_cache_config));
2237836SJohn.Forte@Sun.COM
2247836SJohn.Forte@Sun.COM /* copy in mgmt config info */
2257836SJohn.Forte@Sun.COM
2267836SJohn.Forte@Sun.COM _sd_cache_config.magic = mgmt->magic;
2277836SJohn.Forte@Sun.COM _sd_cache_config.threads = mgmt->threads;
2287836SJohn.Forte@Sun.COM
2297836SJohn.Forte@Sun.COM for (i = 0; i < CACHE_MEM_PAD; i++) {
2307836SJohn.Forte@Sun.COM _sd_cache_config.cache_mem[i] = mgmt->cache_mem[i];
2317836SJohn.Forte@Sun.COM }
2327836SJohn.Forte@Sun.COM
2337836SJohn.Forte@Sun.COM /* fake the rest as a single node config */
2347836SJohn.Forte@Sun.COM
2357836SJohn.Forte@Sun.COM _sd_cache_config.nodes_conf[0] = nsc_node_id();
2367836SJohn.Forte@Sun.COM _sd_cache_config.num_nodes = 1;
2377836SJohn.Forte@Sun.COM }
2387836SJohn.Forte@Sun.COM
2397836SJohn.Forte@Sun.COM /*
2407836SJohn.Forte@Sun.COM * Check that the requested cache size doesn't break the code.
2417836SJohn.Forte@Sun.COM * This test can be refined once the cache size is stored in variables
2427836SJohn.Forte@Sun.COM * larger than an int.
2437836SJohn.Forte@Sun.COM */
2447836SJohn.Forte@Sun.COM for (i = 0; i < MAX_CACHE_NET; i++) {
2457836SJohn.Forte@Sun.COM if (_sd_cache_config.cache_mem[i] < 0) {
246*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!_sdbc_configure: "
2477836SJohn.Forte@Sun.COM "negative cache size (%d) for net %d",
2487836SJohn.Forte@Sun.COM _sd_cache_config.cache_mem[i], i);
2497836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_ENONETMEM);
2507836SJohn.Forte@Sun.COM rc = SDBC_ENONETMEM;
2517836SJohn.Forte@Sun.COM goto out;
2527836SJohn.Forte@Sun.COM }
2537836SJohn.Forte@Sun.COM if (_sd_cache_config.cache_mem[i] > MAX_CACHE_SIZE) {
2547836SJohn.Forte@Sun.COM _sd_cache_config.cache_mem[i] = MAX_CACHE_SIZE;
255*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!_sdbc_configure: "
2567836SJohn.Forte@Sun.COM "cache size limited to %d megabytes for net %d",
2577836SJohn.Forte@Sun.COM MAX_CACHE_SIZE, i);
2587836SJohn.Forte@Sun.COM }
2597836SJohn.Forte@Sun.COM }
2607836SJohn.Forte@Sun.COM
2617836SJohn.Forte@Sun.COM if (_sd_cache_config.blk_size == 0)
2627836SJohn.Forte@Sun.COM _sd_cache_config.blk_size = 8192;
2637836SJohn.Forte@Sun.COM
2647836SJohn.Forte@Sun.COM if (_sd_cache_config.procs == 0)
2657836SJohn.Forte@Sun.COM _sd_cache_config.procs = 16;
2667836SJohn.Forte@Sun.COM
2677836SJohn.Forte@Sun.COM #if !defined(_SD_8K_BLKSIZE)
2687836SJohn.Forte@Sun.COM if (_sd_cache_config.blk_size != 4096) {
2697836SJohn.Forte@Sun.COM #else
2707836SJohn.Forte@Sun.COM if (_sd_cache_config.blk_size != 8192) {
2717836SJohn.Forte@Sun.COM #endif
2727836SJohn.Forte@Sun.COM (void) spcs_s_inttostring(_sd_cache_config.blk_size, itmp,
2737836SJohn.Forte@Sun.COM sizeof (itmp), 0);
2747836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_ESIZE, itmp);
2757836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
2767836SJohn.Forte@Sun.COM goto out;
2777836SJohn.Forte@Sun.COM }
2787836SJohn.Forte@Sun.COM if (((_sd_cblock_shift =
2797836SJohn.Forte@Sun.COM get_high_bit(_sd_cache_config.blk_size)) == -1) ||
2807836SJohn.Forte@Sun.COM (_sd_cache_config.blk_size != (1 << _sd_cblock_shift))) {
2817836SJohn.Forte@Sun.COM (void) spcs_s_inttostring(_sd_cache_config.blk_size, itmp,
2827836SJohn.Forte@Sun.COM sizeof (itmp), 0);
2837836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_ESIZE, itmp);
2847836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
2857836SJohn.Forte@Sun.COM goto out;
2867836SJohn.Forte@Sun.COM }
2877836SJohn.Forte@Sun.COM
2887836SJohn.Forte@Sun.COM if (_sd_cache_config.magic != _SD_MAGIC) {
2897836SJohn.Forte@Sun.COM rc = SDBC_EMAGIC;
2907836SJohn.Forte@Sun.COM goto out;
2917836SJohn.Forte@Sun.COM }
2927836SJohn.Forte@Sun.COM
2937836SJohn.Forte@Sun.COM sdbc_use_dmchain = (_sd_cache_config.reserved1 & CFG_USE_DMCHAIN);
2947836SJohn.Forte@Sun.COM sdbc_static_cache = (_sd_cache_config.reserved1 & CFG_STATIC_CACHE);
2957836SJohn.Forte@Sun.COM
2967836SJohn.Forte@Sun.COM _sdbc_nodeid_configure();
2977836SJohn.Forte@Sun.COM
2987836SJohn.Forte@Sun.COM if (_SD_SELF_HOST > nsc_max_nodeid ||
2997836SJohn.Forte@Sun.COM _SD_MIRROR_HOST > nsc_max_nodeid) {
3007836SJohn.Forte@Sun.COM (void) spcs_s_inttostring((_SD_SELF_HOST > nsc_max_nodeid ?
3017836SJohn.Forte@Sun.COM _SD_SELF_HOST : _SD_MIRROR_HOST), itmp, sizeof (itmp), 0);
3027836SJohn.Forte@Sun.COM (void) spcs_s_inttostring(
3037836SJohn.Forte@Sun.COM nsc_max_nodeid, itmp2, sizeof (itmp2), 0);
3047836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_EINVHOSTID, itmp, itmp2);
3057836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
3067836SJohn.Forte@Sun.COM goto out;
3077836SJohn.Forte@Sun.COM }
3087836SJohn.Forte@Sun.COM
3097836SJohn.Forte@Sun.COM
3107836SJohn.Forte@Sun.COM if (_SD_SELF_HOST == _SD_MIRROR_HOST) {
3117836SJohn.Forte@Sun.COM (void) spcs_s_inttostring(
3127836SJohn.Forte@Sun.COM _SD_SELF_HOST, itmp, sizeof (itmp), 0);
3137836SJohn.Forte@Sun.COM (void) spcs_s_inttostring(
3147836SJohn.Forte@Sun.COM _SD_MIRROR_HOST, itmp2, sizeof (itmp2), 0);
3157836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_ENOTSAME, itmp, itmp2);
3167836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
3177836SJohn.Forte@Sun.COM goto out;
3187836SJohn.Forte@Sun.COM }
3197836SJohn.Forte@Sun.COM
3207836SJohn.Forte@Sun.COM /* initialize the safestore modules */
3217836SJohn.Forte@Sun.COM sst_init();
3227836SJohn.Forte@Sun.COM
3237836SJohn.Forte@Sun.COM /* figure out which kind of safestore we need to use */
3247836SJohn.Forte@Sun.COM ss_type = sdbc_determine_safestore();
3257836SJohn.Forte@Sun.COM
3267836SJohn.Forte@Sun.COM tryss:
3277836SJohn.Forte@Sun.COM /* open and configure the safestore module */
3287836SJohn.Forte@Sun.COM if ((sdbc_safestore = sst_open(ss_type, 0)) == NULL) {
329*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!cannot open safestore module for type %x",
3307836SJohn.Forte@Sun.COM ss_type);
3317836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
3327836SJohn.Forte@Sun.COM goto out;
3337836SJohn.Forte@Sun.COM } else {
3347836SJohn.Forte@Sun.COM sd_setup_ssconfig();
3357836SJohn.Forte@Sun.COM if (SSOP_CONFIGURE(sdbc_safestore, &safestore_config,
3367836SJohn.Forte@Sun.COM spcs_kstatus)) {
3377836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
338*9093SRamana.Srikanth@Sun.COM "!cannot configure safestore module for type %x",
3397836SJohn.Forte@Sun.COM ss_type);
3407836SJohn.Forte@Sun.COM (void) sst_close(sdbc_safestore);
3417836SJohn.Forte@Sun.COM
3427836SJohn.Forte@Sun.COM /* try ram if possible, otherwise return */
3437836SJohn.Forte@Sun.COM if ((ss_type & (SS_M_RAM | SS_T_NONE)) ==
3447836SJohn.Forte@Sun.COM (SS_M_RAM | SS_T_NONE)) {
3457836SJohn.Forte@Sun.COM rc = SDBC_EENABLEFAIL;
3467836SJohn.Forte@Sun.COM goto out;
3477836SJohn.Forte@Sun.COM }
3487836SJohn.Forte@Sun.COM
3497836SJohn.Forte@Sun.COM ss_type = (SS_M_RAM | SS_T_NONE);
3507836SJohn.Forte@Sun.COM goto tryss;
3517836SJohn.Forte@Sun.COM }
3527836SJohn.Forte@Sun.COM }
3537836SJohn.Forte@Sun.COM
3547836SJohn.Forte@Sun.COM if (SAFESTORE_LOCAL(sdbc_safestore))
3557836SJohn.Forte@Sun.COM _SD_MIRROR_HOST = _SD_NO_HOST;
3567836SJohn.Forte@Sun.COM
3577836SJohn.Forte@Sun.COM ASSERT(safestore_config.ssc_ss_psize <= UINT16_MAX); /* LINTED */
3587836SJohn.Forte@Sun.COM _sd_net_config.sn_psize = safestore_config.ssc_ss_psize;
3597836SJohn.Forte@Sun.COM
3607836SJohn.Forte@Sun.COM
3617836SJohn.Forte@Sun.COM _sd_net_config.sn_csize =
362*9093SRamana.Srikanth@Sun.COM _sd_cache_config.cache_mem[_SD_NO_NET] * MEGABYTE;
3637836SJohn.Forte@Sun.COM _sd_net_config.sn_cpages =
364*9093SRamana.Srikanth@Sun.COM _sd_net_config.sn_csize / BLK_SIZE(1);
3657836SJohn.Forte@Sun.COM
3667836SJohn.Forte@Sun.COM _sd_net_config.sn_configured = 1;
3677836SJohn.Forte@Sun.COM cache_bytes = _sd_net_config.sn_cpages * BLK_SIZE(1);
3687836SJohn.Forte@Sun.COM
3697836SJohn.Forte@Sun.COM if (_sdbc_memtype_configure()) {
3707836SJohn.Forte@Sun.COM rc = EINVAL;
3717836SJohn.Forte@Sun.COM goto out;
3727836SJohn.Forte@Sun.COM }
3737836SJohn.Forte@Sun.COM
3747836SJohn.Forte@Sun.COM if ((rc = _sdbc_iobuf_configure(_sd_cache_config.iobuf))) {
3757836SJohn.Forte@Sun.COM if (rc == -1) {
3767836SJohn.Forte@Sun.COM rc = SDBC_ENOIOBMEM;
3777836SJohn.Forte@Sun.COM goto out;
3787836SJohn.Forte@Sun.COM }
3797836SJohn.Forte@Sun.COM if (rc == -2) {
3807836SJohn.Forte@Sun.COM rc = SDBC_ENOIOBCB;
3817836SJohn.Forte@Sun.COM goto out;
3827836SJohn.Forte@Sun.COM }
3837836SJohn.Forte@Sun.COM
3847836SJohn.Forte@Sun.COM }
3857836SJohn.Forte@Sun.COM
3867836SJohn.Forte@Sun.COM if (_sdbc_handles_configure()) {
3877836SJohn.Forte@Sun.COM rc = SDBC_ENOHANDLEMEM;
3887836SJohn.Forte@Sun.COM goto out;
3897836SJohn.Forte@Sun.COM }
3907836SJohn.Forte@Sun.COM
3917836SJohn.Forte@Sun.COM _sd_cache_dem_cnt = 0;
3927836SJohn.Forte@Sun.COM
3937836SJohn.Forte@Sun.COM
3947836SJohn.Forte@Sun.COM /*
3957836SJohn.Forte@Sun.COM * nvmem support:
3967836SJohn.Forte@Sun.COM * if the cache did not shutdown properly we mark it as dirty.
3977836SJohn.Forte@Sun.COM * this must be done before _sdbc_cache_configure() so it can
3987836SJohn.Forte@Sun.COM * refresh sd_info_mem and sd_file_mem from nvmem if necsssary,
3997836SJohn.Forte@Sun.COM * and before _sdbc_ft_configure() so the ft thread will do a recovery.
4007836SJohn.Forte@Sun.COM *
4017836SJohn.Forte@Sun.COM */
4027836SJohn.Forte@Sun.COM if (SAFESTORE_RECOVERY(sdbc_safestore)) {
4037836SJohn.Forte@Sun.COM _sdbc_set_warm_start();
4047836SJohn.Forte@Sun.COM _sdbc_ft_hold_io = 1;
4057836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
406*9093SRamana.Srikanth@Sun.COM "!sdbc(_sdbc_configure) cache marked dirty after"
4077836SJohn.Forte@Sun.COM " incomplete shutdown");
4087836SJohn.Forte@Sun.COM }
4097836SJohn.Forte@Sun.COM
4107836SJohn.Forte@Sun.COM if ((rc = _sdbc_cache_configure(cache_bytes / BLK_SIZE(1),
4117836SJohn.Forte@Sun.COM spcs_kstatus))) {
4127836SJohn.Forte@Sun.COM goto out;
4137836SJohn.Forte@Sun.COM }
4147836SJohn.Forte@Sun.COM
4157836SJohn.Forte@Sun.COM
4167836SJohn.Forte@Sun.COM /* ST_ALERT trace buffer */
4177836SJohn.Forte@Sun.COM if (_sdbc_tr_configure(-1 /* SDT_INV_CD */) != 0) {
4187836SJohn.Forte@Sun.COM rc = EINVAL;
4197836SJohn.Forte@Sun.COM goto out;
4207836SJohn.Forte@Sun.COM }
4217836SJohn.Forte@Sun.COM
4227836SJohn.Forte@Sun.COM if (_sdbc_thread_configure()) {
4237836SJohn.Forte@Sun.COM rc = SDBC_EFLUSHTHRD;
4247836SJohn.Forte@Sun.COM goto out;
4257836SJohn.Forte@Sun.COM }
4267836SJohn.Forte@Sun.COM
4277836SJohn.Forte@Sun.COM if (_sdbc_flush_configure()) {
4287836SJohn.Forte@Sun.COM rc = EINVAL;
4297836SJohn.Forte@Sun.COM goto out;
4307836SJohn.Forte@Sun.COM }
4317836SJohn.Forte@Sun.COM
4327836SJohn.Forte@Sun.COM if (rc = _sdbc_dealloc_configure_dm()) {
4337836SJohn.Forte@Sun.COM goto out;
4347836SJohn.Forte@Sun.COM }
4357836SJohn.Forte@Sun.COM
4367836SJohn.Forte@Sun.COM if (_sd_cache_config.test_demons)
4377836SJohn.Forte@Sun.COM if (_sdbc_tdaemon_configure(_sd_cache_config.test_demons)) {
4387836SJohn.Forte@Sun.COM rc = EINVAL;
4397836SJohn.Forte@Sun.COM goto out;
4407836SJohn.Forte@Sun.COM }
4417836SJohn.Forte@Sun.COM
4427836SJohn.Forte@Sun.COM
4437836SJohn.Forte@Sun.COM _sd_cache_initialized = 1;
4447836SJohn.Forte@Sun.COM
4457836SJohn.Forte@Sun.COM sdbc_power = nsc_register_power("sdbc", _sdbc_power_def);
4467836SJohn.Forte@Sun.COM
4477836SJohn.Forte@Sun.COM if (_sdbc_ft_configure() != 0) {
4487836SJohn.Forte@Sun.COM rc = EINVAL;
4497836SJohn.Forte@Sun.COM goto out;
4507836SJohn.Forte@Sun.COM }
4517836SJohn.Forte@Sun.COM
4527836SJohn.Forte@Sun.COM /*
4537836SJohn.Forte@Sun.COM * try to control the race between the ft thread
4547836SJohn.Forte@Sun.COM * and threads that will open the devices that the ft thread
4557836SJohn.Forte@Sun.COM * may be recovering. this synchronizing with the ft thread
4567836SJohn.Forte@Sun.COM * prevents sd_cadmin from returning until ft has opened
4577836SJohn.Forte@Sun.COM * the recovery devices, so if other apps wait for sd_cadmin
4587836SJohn.Forte@Sun.COM * to complete the race is prevented.
4597836SJohn.Forte@Sun.COM */
4607836SJohn.Forte@Sun.COM mutex_enter(&_sdbc_ft_hold_io_lk);
4617836SJohn.Forte@Sun.COM while (_sdbc_ft_hold_io) {
4627836SJohn.Forte@Sun.COM cv_wait(&_sdbc_ft_hold_io_cv, &_sdbc_ft_hold_io_lk);
4637836SJohn.Forte@Sun.COM }
4647836SJohn.Forte@Sun.COM
4657836SJohn.Forte@Sun.COM io = nsc_register_io("sdbc", NSC_SDBC_ID|NSC_FILTER,
4667836SJohn.Forte@Sun.COM _sd_sdbc_def);
4677836SJohn.Forte@Sun.COM
4687836SJohn.Forte@Sun.COM if (io) sdbc_io = io;
4697836SJohn.Forte@Sun.COM
4707836SJohn.Forte@Sun.COM mutex_exit(&_sdbc_ft_hold_io_lk);
4717836SJohn.Forte@Sun.COM
4727836SJohn.Forte@Sun.COM #ifdef DEBUG
473*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sd_config: Cache has been configured");
4747836SJohn.Forte@Sun.COM #endif
4757836SJohn.Forte@Sun.COM
4767836SJohn.Forte@Sun.COM rc = 0;
4777836SJohn.Forte@Sun.COM
4787836SJohn.Forte@Sun.COM out:
4797836SJohn.Forte@Sun.COM return (rc);
4807836SJohn.Forte@Sun.COM }
4817836SJohn.Forte@Sun.COM
4827836SJohn.Forte@Sun.COM /*
4837836SJohn.Forte@Sun.COM * _sdbc_deconfigure - Put the cache back to the unconfigured state. Release
4847836SJohn.Forte@Sun.COM * any memory we allocated as part of the configuration process (but not the
4857836SJohn.Forte@Sun.COM * load/init process). Put globals back to unconfigured state and shut down
4867836SJohn.Forte@Sun.COM * any processes/threads we have running.
4877836SJohn.Forte@Sun.COM *
4887836SJohn.Forte@Sun.COM * Since the cache has loaded we know that global lock/sv's are present and
4897836SJohn.Forte@Sun.COM * we can use them to produce an orderly deconfiguration.
4907836SJohn.Forte@Sun.COM *
4917836SJohn.Forte@Sun.COM * NOTE: this routine and its callee should always be capable of reversing
4927836SJohn.Forte@Sun.COM * the effects of _sdbc_configure no matter what partially configured
4937836SJohn.Forte@Sun.COM * state might be present.
4947836SJohn.Forte@Sun.COM *
4957836SJohn.Forte@Sun.COM */
4967836SJohn.Forte@Sun.COM int
4977836SJohn.Forte@Sun.COM _sdbc_deconfigure(spcs_s_info_t spcs_kstatus)
4987836SJohn.Forte@Sun.COM {
4997836SJohn.Forte@Sun.COM int i;
5007836SJohn.Forte@Sun.COM _sd_cd_info_t *cdi;
5017836SJohn.Forte@Sun.COM int rc;
5027836SJohn.Forte@Sun.COM int pinneddata = 0;
5037836SJohn.Forte@Sun.COM uint_t saved_hint;
5047836SJohn.Forte@Sun.COM
5057836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&_sdbc_config_lock));
5067836SJohn.Forte@Sun.COM
5077836SJohn.Forte@Sun.COM #ifdef DEBUG
508*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SD cache being deconfigured.");
5097836SJohn.Forte@Sun.COM #endif
5107836SJohn.Forte@Sun.COM
5117836SJohn.Forte@Sun.COM /* check if there is pinned data and our mirror is down */
5127836SJohn.Forte@Sun.COM if (_sd_cache_files && _sd_is_mirror_down()) {
5137836SJohn.Forte@Sun.COM for (i = 0; i < sdbc_max_devs; i++) {
5147836SJohn.Forte@Sun.COM cdi = &(_sd_cache_files[i]);
5157836SJohn.Forte@Sun.COM if (cdi->cd_info == NULL)
5167836SJohn.Forte@Sun.COM continue;
5177836SJohn.Forte@Sun.COM /*
5187836SJohn.Forte@Sun.COM * if (!(cdi->cd_info->sh_failed))
5197836SJohn.Forte@Sun.COM * continue;
5207836SJohn.Forte@Sun.COM */
5217836SJohn.Forte@Sun.COM if (!(_SD_CD_ALL_WRITES(i)))
5227836SJohn.Forte@Sun.COM continue;
5237836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_EPINNED,
524*9093SRamana.Srikanth@Sun.COM cdi->cd_info->sh_filename);
5257836SJohn.Forte@Sun.COM rc = SDBC_EDISABLEFAIL;
5267836SJohn.Forte@Sun.COM goto out;
5277836SJohn.Forte@Sun.COM }
5287836SJohn.Forte@Sun.COM }
5297836SJohn.Forte@Sun.COM
5307836SJohn.Forte@Sun.COM /* remember hint setting for restoration in case shutdown fails */
5317836SJohn.Forte@Sun.COM (void) _sd_get_node_hint(&saved_hint);
5327836SJohn.Forte@Sun.COM
5337836SJohn.Forte@Sun.COM (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
5347836SJohn.Forte@Sun.COM
5357836SJohn.Forte@Sun.COM
5367836SJohn.Forte@Sun.COM /* TODO - there is a possible race between deconfig and power hits... */
5377836SJohn.Forte@Sun.COM
5387836SJohn.Forte@Sun.COM if (sdbc_power)
5397836SJohn.Forte@Sun.COM (void) nsc_unregister_power(sdbc_power);
5407836SJohn.Forte@Sun.COM
5417836SJohn.Forte@Sun.COM
5427836SJohn.Forte@Sun.COM if (sdbc_io) {
5437836SJohn.Forte@Sun.COM rc = nsc_unregister_io(sdbc_io, NSC_PCATCH);
5447836SJohn.Forte@Sun.COM if (rc == 0)
5457836SJohn.Forte@Sun.COM sdbc_io = NULL;
5467836SJohn.Forte@Sun.COM else {
5477836SJohn.Forte@Sun.COM if (rc == EUSERS)
5487836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_EABUFS);
5497836SJohn.Forte@Sun.COM
5507836SJohn.Forte@Sun.COM spcs_s_add(spcs_kstatus, SDBC_EUNREG);
5517836SJohn.Forte@Sun.COM
5527836SJohn.Forte@Sun.COM /* Re-register-power if it was register before. */
5537836SJohn.Forte@Sun.COM if (sdbc_power) {
5547836SJohn.Forte@Sun.COM sdbc_power = nsc_register_power("sdbc",
555*9093SRamana.Srikanth@Sun.COM _sdbc_power_def);
5567836SJohn.Forte@Sun.COM }
5577836SJohn.Forte@Sun.COM
5587836SJohn.Forte@Sun.COM /* Remove NSC_FORCED_WRTHRU if we set it */
5597836SJohn.Forte@Sun.COM (void) _sd_clear_node_hint(
560*9093SRamana.Srikanth@Sun.COM (~saved_hint) & _SD_HINT_MASK);
5617836SJohn.Forte@Sun.COM
5627836SJohn.Forte@Sun.COM rc = SDBC_EDISABLEFAIL;
5637836SJohn.Forte@Sun.COM goto out;
5647836SJohn.Forte@Sun.COM }
5657836SJohn.Forte@Sun.COM }
5667836SJohn.Forte@Sun.COM
5677836SJohn.Forte@Sun.COM sdbc_power = NULL;
5687836SJohn.Forte@Sun.COM
5697836SJohn.Forte@Sun.COM #if defined(_SD_FAULT_RES)
5707836SJohn.Forte@Sun.COM _sd_remote_disable(0); /* notify mirror to forced_wrthru */
5717836SJohn.Forte@Sun.COM #endif
5727836SJohn.Forte@Sun.COM /*
5737836SJohn.Forte@Sun.COM * close devices, deconfigure processes, wait for exits
5747836SJohn.Forte@Sun.COM */
5757836SJohn.Forte@Sun.COM _sdbc_tdaemon_deconfigure();
5767836SJohn.Forte@Sun.COM
5777836SJohn.Forte@Sun.COM if (_sd_cache_files) {
5787836SJohn.Forte@Sun.COM for (i = 0; i < sdbc_max_devs; i++) {
5797836SJohn.Forte@Sun.COM if (FILE_OPENED(i) && ((rc = _sd_close(i)) > 0)) {
580*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!sdbc(_sd_deconfigure)"
5817836SJohn.Forte@Sun.COM " %d not closed (%d)\n", i, rc);
5827836SJohn.Forte@Sun.COM }
5837836SJohn.Forte@Sun.COM }
5847836SJohn.Forte@Sun.COM }
5857836SJohn.Forte@Sun.COM
5867836SJohn.Forte@Sun.COM /*
5877836SJohn.Forte@Sun.COM * look for pinned data
5887836SJohn.Forte@Sun.COM * TODO sort this out for multinode systems.
5897836SJohn.Forte@Sun.COM * cannot shutdown with pinned data on multinode.
5907836SJohn.Forte@Sun.COM * the state of pinned data should be determined in
5917836SJohn.Forte@Sun.COM * the close operation.
5927836SJohn.Forte@Sun.COM */
5937836SJohn.Forte@Sun.COM if (_sd_cache_files) {
5947836SJohn.Forte@Sun.COM for (i = 0; i < sdbc_max_devs; i++) {
5957836SJohn.Forte@Sun.COM cdi = &(_sd_cache_files[i]);
5967836SJohn.Forte@Sun.COM if (cdi->cd_info == NULL)
5977836SJohn.Forte@Sun.COM continue;
5987836SJohn.Forte@Sun.COM /*
5997836SJohn.Forte@Sun.COM * if (!(cdi->cd_info->sh_failed))
6007836SJohn.Forte@Sun.COM * continue;
6017836SJohn.Forte@Sun.COM */
6027836SJohn.Forte@Sun.COM if (!(_SD_CD_ALL_WRITES(i)))
6037836SJohn.Forte@Sun.COM continue;
6047836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
605*9093SRamana.Srikanth@Sun.COM "!sdbc(_sd_deconfigure) Pinned Data on cd %d(%s)",
6067836SJohn.Forte@Sun.COM i, cdi->cd_info->sh_filename);
6077836SJohn.Forte@Sun.COM pinneddata++;
6087836SJohn.Forte@Sun.COM }
6097836SJohn.Forte@Sun.COM }
6107836SJohn.Forte@Sun.COM
6117836SJohn.Forte@Sun.COM _sd_cache_initialized = 0;
6127836SJohn.Forte@Sun.COM
6137836SJohn.Forte@Sun.COM _sdbc_ft_deconfigure();
6147836SJohn.Forte@Sun.COM
6157836SJohn.Forte@Sun.COM _sdbc_flush_deconfigure();
6167836SJohn.Forte@Sun.COM _sdbc_thread_deconfigure();
6177836SJohn.Forte@Sun.COM
6187836SJohn.Forte@Sun.COM mutex_enter(&_sd_cache_lock);
6197836SJohn.Forte@Sun.COM
6207836SJohn.Forte@Sun.COM while (_sd_cache_dem_cnt > 0) {
6217836SJohn.Forte@Sun.COM mutex_exit(&_sd_cache_lock);
6227836SJohn.Forte@Sun.COM (void) nsc_delay_sig(HZ/2);
6237836SJohn.Forte@Sun.COM mutex_enter(&_sd_cache_lock);
6247836SJohn.Forte@Sun.COM }
6257836SJohn.Forte@Sun.COM mutex_exit(&_sd_cache_lock);
6267836SJohn.Forte@Sun.COM
6277836SJohn.Forte@Sun.COM /*
6287836SJohn.Forte@Sun.COM * remove all dynamically allocated cache data memory
6297836SJohn.Forte@Sun.COM * there should be no i/o at this point
6307836SJohn.Forte@Sun.COM */
6317836SJohn.Forte@Sun.COM _sdbc_dealloc_deconfigure_dm();
6327836SJohn.Forte@Sun.COM /*
6337836SJohn.Forte@Sun.COM * At this point no thread of control should be active in the cache
6347836SJohn.Forte@Sun.COM * but us (unless they are blocked on the config lock).
6357836SJohn.Forte@Sun.COM */
6367836SJohn.Forte@Sun.COM
6377836SJohn.Forte@Sun.COM
6387836SJohn.Forte@Sun.COM #if defined(_SD_FAULT_RES)
6397836SJohn.Forte@Sun.COM _sd_remote_disable(1); /* notify mirror I/O shutdown complete */
6407836SJohn.Forte@Sun.COM #endif
6417836SJohn.Forte@Sun.COM
6427836SJohn.Forte@Sun.COM #define KEEP_TRACES 0 /* set to 1 keep traces after deconfig */
6437836SJohn.Forte@Sun.COM #if !KEEP_TRACES
6447836SJohn.Forte@Sun.COM /*
6457836SJohn.Forte@Sun.COM * This needs to happen before we unregister the memory.
6467836SJohn.Forte@Sun.COM */
6477836SJohn.Forte@Sun.COM _sdbc_tr_deconfigure();
6487836SJohn.Forte@Sun.COM #endif
6497836SJohn.Forte@Sun.COM
6507836SJohn.Forte@Sun.COM
6517836SJohn.Forte@Sun.COM /* delete/free hash table, cache blocks, etc */
6527836SJohn.Forte@Sun.COM _sdbc_cache_deconfigure();
6537836SJohn.Forte@Sun.COM
6547836SJohn.Forte@Sun.COM _sdbc_handles_deconfigure();
6557836SJohn.Forte@Sun.COM
6567836SJohn.Forte@Sun.COM _sdbc_iobuf_deconfigure();
6577836SJohn.Forte@Sun.COM
6587836SJohn.Forte@Sun.COM #if !KEEP_TRACES
6597836SJohn.Forte@Sun.COM if (!_sdbc_memtype_deconfigure_delayed)
6607836SJohn.Forte@Sun.COM _sdbc_memtype_deconfigure();
6617836SJohn.Forte@Sun.COM #else
6627836SJohn.Forte@Sun.COM _sdbc_memtype_deconfigure_delayed = 1;
6637836SJohn.Forte@Sun.COM #endif
6647836SJohn.Forte@Sun.COM
6657836SJohn.Forte@Sun.COM /*
6667836SJohn.Forte@Sun.COM * Call ss deconfig(),
6677836SJohn.Forte@Sun.COM * check for valid pointer in case _sdbc_configure()
6687836SJohn.Forte@Sun.COM * failed before safestrore system was initialized.
6697836SJohn.Forte@Sun.COM */
6707836SJohn.Forte@Sun.COM if (sdbc_safestore)
6717836SJohn.Forte@Sun.COM SSOP_DECONFIGURE(sdbc_safestore, pinneddata);
6727836SJohn.Forte@Sun.COM
6737836SJohn.Forte@Sun.COM /* tear down safestore system */
6747836SJohn.Forte@Sun.COM sst_deinit();
6757836SJohn.Forte@Sun.COM
6767836SJohn.Forte@Sun.COM _sdbc_nodeid_deconfigure();
6777836SJohn.Forte@Sun.COM
6787836SJohn.Forte@Sun.COM bzero(&_sd_cache_config, sizeof (_sd_cache_param_t));
6797836SJohn.Forte@Sun.COM
6807836SJohn.Forte@Sun.COM _SD_SELF_HOST = _SD_MIRROR_HOST = _SD_NO_HOST;
6817836SJohn.Forte@Sun.COM _SD_NETS = 0;
6827836SJohn.Forte@Sun.COM _sd_cblock_shift = 0;
6837836SJohn.Forte@Sun.COM _sd_node_hint = 0;
6847836SJohn.Forte@Sun.COM
6857836SJohn.Forte@Sun.COM #ifdef DEBUG
686*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SD cache deconfigured.");
6877836SJohn.Forte@Sun.COM #endif
6887836SJohn.Forte@Sun.COM
6897836SJohn.Forte@Sun.COM rc = 0;
6907836SJohn.Forte@Sun.COM
6917836SJohn.Forte@Sun.COM out:
6927836SJohn.Forte@Sun.COM return (rc);
6937836SJohn.Forte@Sun.COM }
6947836SJohn.Forte@Sun.COM
6957836SJohn.Forte@Sun.COM
6967836SJohn.Forte@Sun.COM
6977836SJohn.Forte@Sun.COM static int
6987836SJohn.Forte@Sun.COM find_low_bit(int mask, int start)
6997836SJohn.Forte@Sun.COM {
7007836SJohn.Forte@Sun.COM for (; start < 32; start++)
7017836SJohn.Forte@Sun.COM if ((mask & (1 << start)))
7027836SJohn.Forte@Sun.COM break;
7037836SJohn.Forte@Sun.COM
7047836SJohn.Forte@Sun.COM return (start);
7057836SJohn.Forte@Sun.COM }
7067836SJohn.Forte@Sun.COM
7077836SJohn.Forte@Sun.COM int
7087836SJohn.Forte@Sun.COM get_high_bit(int size)
7097836SJohn.Forte@Sun.COM {
7107836SJohn.Forte@Sun.COM int lowbit;
7117836SJohn.Forte@Sun.COM int newblk = size;
7127836SJohn.Forte@Sun.COM int highbit = -1;
7137836SJohn.Forte@Sun.COM int next_high = 0;
7147836SJohn.Forte@Sun.COM
7157836SJohn.Forte@Sun.COM while ((lowbit = find_low_bit(newblk, 0)) != 32) {
7167836SJohn.Forte@Sun.COM if (highbit >= 0) next_high = 1;
7177836SJohn.Forte@Sun.COM highbit = lowbit;
7187836SJohn.Forte@Sun.COM newblk &= ~(1 << highbit);
7197836SJohn.Forte@Sun.COM }
7207836SJohn.Forte@Sun.COM
7217836SJohn.Forte@Sun.COM if (highbit <= 0) {
7227836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
723*9093SRamana.Srikanth@Sun.COM "!sdbc(get_high_bit) invalid block size %x\n", size);
7247836SJohn.Forte@Sun.COM return (-1);
7257836SJohn.Forte@Sun.COM }
7267836SJohn.Forte@Sun.COM
7277836SJohn.Forte@Sun.COM if (next_high) highbit++;
7287836SJohn.Forte@Sun.COM
7297836SJohn.Forte@Sun.COM return (highbit);
7307836SJohn.Forte@Sun.COM }
7317836SJohn.Forte@Sun.COM
7327836SJohn.Forte@Sun.COM
7337836SJohn.Forte@Sun.COM int
7347836SJohn.Forte@Sun.COM _sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size)
7357836SJohn.Forte@Sun.COM {
7367836SJohn.Forte@Sun.COM caddr_t fmt_page;
7377836SJohn.Forte@Sun.COM int i, page_size;
7387836SJohn.Forte@Sun.COM
7397836SJohn.Forte@Sun.COM page_size = (int)ptob(1);
7407836SJohn.Forte@Sun.COM
7417836SJohn.Forte@Sun.COM if ((fmt_page = (caddr_t)nsc_kmem_alloc(ptob(1),
7427836SJohn.Forte@Sun.COM KM_SLEEP, sdbc_local_mem)) == NULL) {
743*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!sdbc(_sd_fill pattern) no more memory");
7447836SJohn.Forte@Sun.COM return (-1);
7457836SJohn.Forte@Sun.COM }
7467836SJohn.Forte@Sun.COM for (i = 0; i < page_size; i += 4)
7477836SJohn.Forte@Sun.COM *(int *)(void *)(fmt_page + i) = pat;
7487836SJohn.Forte@Sun.COM
7497836SJohn.Forte@Sun.COM while (size >= page_size) {
7507836SJohn.Forte@Sun.COM bcopy(fmt_page, addr, ptob(1));
7517836SJohn.Forte@Sun.COM addr += page_size;
7527836SJohn.Forte@Sun.COM size -= page_size;
7537836SJohn.Forte@Sun.COM }
7547836SJohn.Forte@Sun.COM nsc_kmem_free(fmt_page, page_size);
7557836SJohn.Forte@Sun.COM return (0);
7567836SJohn.Forte@Sun.COM }
7577836SJohn.Forte@Sun.COM
7587836SJohn.Forte@Sun.COM
7597836SJohn.Forte@Sun.COM /*
7607836SJohn.Forte@Sun.COM * _sdbc_nodeid_deconfigure - merely a place holder until
7617836SJohn.Forte@Sun.COM * such time as there is something to be undone w.r.t.
7627836SJohn.Forte@Sun.COM * _sdbc_nodeid_configure.
7637836SJohn.Forte@Sun.COM *
7647836SJohn.Forte@Sun.COM */
7657836SJohn.Forte@Sun.COM static void
7667836SJohn.Forte@Sun.COM _sdbc_nodeid_deconfigure(void)
7677836SJohn.Forte@Sun.COM {
7687836SJohn.Forte@Sun.COM /* My but we're quick */
7697836SJohn.Forte@Sun.COM }
7707836SJohn.Forte@Sun.COM
7717836SJohn.Forte@Sun.COM /*
7727836SJohn.Forte@Sun.COM * _sdbc_nodeid_configure - configure the nodeid's we need to connect
7737836SJohn.Forte@Sun.COM * to any other nodes in the network.
7747836SJohn.Forte@Sun.COM *
7757836SJohn.Forte@Sun.COM */
7767836SJohn.Forte@Sun.COM void
7777836SJohn.Forte@Sun.COM _sdbc_nodeid_configure(void)
7787836SJohn.Forte@Sun.COM {
7797836SJohn.Forte@Sun.COM
7807836SJohn.Forte@Sun.COM if (_sd_cache_config.num_nodes == 0) {
7817836SJohn.Forte@Sun.COM _sd_nodes_configured = 1;
7827836SJohn.Forte@Sun.COM } else {
7837836SJohn.Forte@Sun.COM _sd_nodes_configured = _sd_cache_config.num_nodes;
7847836SJohn.Forte@Sun.COM }
7857836SJohn.Forte@Sun.COM
7867836SJohn.Forte@Sun.COM _SD_SELF_HOST = nsc_node_id();
7877836SJohn.Forte@Sun.COM _SD_MIRROR_HOST = _sd_cache_config.mirror_host;
7887836SJohn.Forte@Sun.COM }
7897836SJohn.Forte@Sun.COM
7907836SJohn.Forte@Sun.COM #define STACK_SIZE (32*1024)
7917836SJohn.Forte@Sun.COM #define num_spin 0
7927836SJohn.Forte@Sun.COM nstset_t *_sd_ioset;
7937836SJohn.Forte@Sun.COM
7947836SJohn.Forte@Sun.COM /*
7957836SJohn.Forte@Sun.COM * _sdbc_thread_deconfigure - cache is being deconfigure, stop any
7967836SJohn.Forte@Sun.COM * thread activity.
7977836SJohn.Forte@Sun.COM *
7987836SJohn.Forte@Sun.COM */
7997836SJohn.Forte@Sun.COM static void
8007836SJohn.Forte@Sun.COM _sdbc_thread_deconfigure(void)
8017836SJohn.Forte@Sun.COM {
8027836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&_sdbc_config_lock));
8037836SJohn.Forte@Sun.COM nst_destroy(_sd_ioset);
8047836SJohn.Forte@Sun.COM _sd_ioset = NULL;
8057836SJohn.Forte@Sun.COM }
8067836SJohn.Forte@Sun.COM
8077836SJohn.Forte@Sun.COM /*
8087836SJohn.Forte@Sun.COM * _sdbc_thread_configure - cache is being configured, initialize the
8097836SJohn.Forte@Sun.COM * threads we need for flushing dirty cds.
8107836SJohn.Forte@Sun.COM *
8117836SJohn.Forte@Sun.COM */
8127836SJohn.Forte@Sun.COM static int
8137836SJohn.Forte@Sun.COM _sdbc_thread_configure(void)
8147836SJohn.Forte@Sun.COM {
8157836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&_sdbc_config_lock));
8167836SJohn.Forte@Sun.COM
8177836SJohn.Forte@Sun.COM if (!_sd_ioset)
8187836SJohn.Forte@Sun.COM _sd_ioset = nst_init("sd_thr", _sd_cache_config.threads);
8197836SJohn.Forte@Sun.COM
8207836SJohn.Forte@Sun.COM if (!_sd_ioset)
8217836SJohn.Forte@Sun.COM return (EINVAL);
8227836SJohn.Forte@Sun.COM
8237836SJohn.Forte@Sun.COM return (0);
8247836SJohn.Forte@Sun.COM }
8257836SJohn.Forte@Sun.COM
8267836SJohn.Forte@Sun.COM int
8277836SJohn.Forte@Sun.COM _sdbc_get_config(_sdbc_config_t *config_info)
8287836SJohn.Forte@Sun.COM {
8297836SJohn.Forte@Sun.COM int i;
8307836SJohn.Forte@Sun.COM
8317836SJohn.Forte@Sun.COM config_info->enabled = _sd_cache_initialized;
8327836SJohn.Forte@Sun.COM config_info->magic = _SD_MAGIC;
8337836SJohn.Forte@Sun.COM for (i = 0; i < CACHE_MEM_PAD; i++) {
8347836SJohn.Forte@Sun.COM config_info->cache_mem[i] = _sd_cache_config.cache_mem[i];
8357836SJohn.Forte@Sun.COM }
8367836SJohn.Forte@Sun.COM config_info->threads = _sd_cache_config.threads;
8377836SJohn.Forte@Sun.COM
8387836SJohn.Forte@Sun.COM return (0);
8397836SJohn.Forte@Sun.COM }
840