xref: /onnv-gate/usr/src/uts/common/avs/ns/sdbc/sd_tdaemon.c (revision 9093:cd587b0bd19c)
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 /*
277836SJohn.Forte@Sun.COM  * Routines for the Infinity Storage Device daemon
287836SJohn.Forte@Sun.COM  */
297836SJohn.Forte@Sun.COM 
307836SJohn.Forte@Sun.COM #include <sys/types.h>
317836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
327836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
337836SJohn.Forte@Sun.COM #include <sys/errno.h>
347836SJohn.Forte@Sun.COM #include <sys/buf.h>
357836SJohn.Forte@Sun.COM #include <sys/kmem.h>
367836SJohn.Forte@Sun.COM #include <sys/cred.h>
377836SJohn.Forte@Sun.COM #include <sys/ddi.h>
387836SJohn.Forte@Sun.COM #include <sys/nsc_thread.h>
397836SJohn.Forte@Sun.COM 
407836SJohn.Forte@Sun.COM #include "sd_bcache.h"
417836SJohn.Forte@Sun.COM #include "sd_io.h"
427836SJohn.Forte@Sun.COM #include "sd_bio.h"
437836SJohn.Forte@Sun.COM #include "sd_ft.h"
447836SJohn.Forte@Sun.COM #include "sd_misc.h"
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM #define	_INFSD_LOCAL_MEM
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM #define	_CD_VTRK_SIZE(cd)	(dev_tsize[GET_CD_STATE(cd)] * 1024)
497836SJohn.Forte@Sun.COM #define	_CD_VTRK_NUM(cd, len)	((len)/_CD_VTRK_SIZE(cd))
507836SJohn.Forte@Sun.COM #define	_CD_VTRK_OFF(cd, len)	((len)%(_CD_VTRK_SIZE(cd)))
517836SJohn.Forte@Sun.COM 
527836SJohn.Forte@Sun.COM #define	FILESIZE (1 << 27) 	/* 128 MB 	*/
537836SJohn.Forte@Sun.COM 
547836SJohn.Forte@Sun.COM #define	SIZEMASK 0x0000FFFF
557836SJohn.Forte@Sun.COM #define	_INFSD_RECORD_SIZE(ndx) REC_SIZE
567836SJohn.Forte@Sun.COM #define	GET_SEED(ndx) (gld[ndx] . seed & SIZEMASK)
577836SJohn.Forte@Sun.COM #define	MAX_CD_STS	600
587836SJohn.Forte@Sun.COM #define	MAX_TDAEMONS  128
597836SJohn.Forte@Sun.COM 
607836SJohn.Forte@Sun.COM static char devarray[MAX_TDAEMONS][MAX_TDAEMONS*2];
617836SJohn.Forte@Sun.COM static int  dev_tsize[MAX_TDAEMONS*2];
627836SJohn.Forte@Sun.COM static int  dev_flag[MAX_TDAEMONS*2];
637836SJohn.Forte@Sun.COM 
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM /*
667836SJohn.Forte@Sun.COM  * sd_test options
677836SJohn.Forte@Sun.COM  */
687836SJohn.Forte@Sun.COM #define	SD_TEST_CACHE_HIT    0x00000001
697836SJohn.Forte@Sun.COM #define	SD_TEST_CACHE_MISS   0x00000002
707836SJohn.Forte@Sun.COM #define	SD_TEST_CHECK_DATA   0x00000004
717836SJohn.Forte@Sun.COM #define	SD_TEST_READ_ONLY    0x00000008
727836SJohn.Forte@Sun.COM #define	SD_TEST_WRITE_ONLY   0x00000010
737836SJohn.Forte@Sun.COM #define	SD_TEST_SEQUENTIAL   0x00000020
747836SJohn.Forte@Sun.COM 
757836SJohn.Forte@Sun.COM static struct cd_sts {
767836SJohn.Forte@Sun.COM 	volatile short  cd_state;
777836SJohn.Forte@Sun.COM 	volatile char waiting;
787836SJohn.Forte@Sun.COM 	volatile char inited;
797836SJohn.Forte@Sun.COM 	kcondvar_t cd_blk;
807836SJohn.Forte@Sun.COM 	volatile caddr_t asy_key;
817836SJohn.Forte@Sun.COM } cd_test_sts[MAX_CD_STS];
827836SJohn.Forte@Sun.COM 
837836SJohn.Forte@Sun.COM #define	SET_CD_STATE(cd, i)	(cd_test_sts[(cd)].cd_state = (short)(i))
847836SJohn.Forte@Sun.COM #define	GET_CD_STATE(cd)	(cd_test_sts[(cd)].cd_state)
857836SJohn.Forte@Sun.COM 
867836SJohn.Forte@Sun.COM static kmutex_t tdaemon_lock;
877836SJohn.Forte@Sun.COM static kcondvar_t _wait_daemons;
887836SJohn.Forte@Sun.COM dev_t	_test_async_fail;	/* fail async writes to cache dev_t */
897836SJohn.Forte@Sun.COM static volatile int 	test_stop;
907836SJohn.Forte@Sun.COM 
917836SJohn.Forte@Sun.COM static int daemon_awake(int i);
927836SJohn.Forte@Sun.COM static void wakeup_all_tdaemons(void);
937836SJohn.Forte@Sun.COM static void _sd_idle_daemon(void);
947836SJohn.Forte@Sun.COM static void _td_detach_cd(int cd);
957836SJohn.Forte@Sun.COM static int _fork_test_daemon(int num_disks, int test_typ, int loop_cnt,
967836SJohn.Forte@Sun.COM     int from, int seed);
977836SJohn.Forte@Sun.COM static void _sd_test_rwloop_seq(int i, int loops, int seed, int forw);
987836SJohn.Forte@Sun.COM static int _sd_copy_pattern_to_handle(_sd_buf_handle_t *handle,
997836SJohn.Forte@Sun.COM     nsc_off_t fba_pos, nsc_size_t fba_len);
1007836SJohn.Forte@Sun.COM static int _sd_copy_handle(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
1017836SJohn.Forte@Sun.COM     nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len, int skew);
1027836SJohn.Forte@Sun.COM static int _sd_compare_handle(_sd_buf_handle_t *handle1,
1037836SJohn.Forte@Sun.COM     _sd_buf_handle_t *handle2, nsc_off_t fba_pos1, nsc_off_t fba_pos2,
1047836SJohn.Forte@Sun.COM     nsc_size_t fba_len, int skew);
1057836SJohn.Forte@Sun.COM static void _sd_direct_test(int c, int loop, int seed, int type);
1067836SJohn.Forte@Sun.COM static void set_parameters(void);
1077836SJohn.Forte@Sun.COM static void test_dma_loop(int net, int seg);
1087836SJohn.Forte@Sun.COM static int _sd_hwrite(_sd_buf_handle_t *buf, nsc_off_t fba_pos,
1097836SJohn.Forte@Sun.COM     nsc_size_t fba_len, int flag);
1107836SJohn.Forte@Sun.COM static void myend(blind_t arg, nsc_off_t fba_pos, nsc_size_t fba_len,
1117836SJohn.Forte@Sun.COM     int error);
1127836SJohn.Forte@Sun.COM static int test_control(int typ, int cd, nsc_off_t fba_pos, nsc_size_t fba_len);
1137836SJohn.Forte@Sun.COM 
1147836SJohn.Forte@Sun.COM int
_sim_write(_sd_buf_handle_t * buf,int x)1157836SJohn.Forte@Sun.COM _sim_write(_sd_buf_handle_t *buf, int x)
1167836SJohn.Forte@Sun.COM {
1177836SJohn.Forte@Sun.COM 	int rval;
1187836SJohn.Forte@Sun.COM 
1197836SJohn.Forte@Sun.COM 	if (test_stop)
1207836SJohn.Forte@Sun.COM 		return (EINVAL);
1217836SJohn.Forte@Sun.COM 	rval = _sd_write(buf, buf->bh_fba_pos, buf->bh_fba_len, x);
1227836SJohn.Forte@Sun.COM 	return (rval == NSC_HIT ? NSC_DONE : rval);
1237836SJohn.Forte@Sun.COM }
1247836SJohn.Forte@Sun.COM 
1257836SJohn.Forte@Sun.COM static int
_sd_hwrite(_sd_buf_handle_t * buf,nsc_off_t fba_pos,nsc_size_t fba_len,int flag)1267836SJohn.Forte@Sun.COM _sd_hwrite(_sd_buf_handle_t *buf, nsc_off_t fba_pos, nsc_size_t fba_len,
1277836SJohn.Forte@Sun.COM     int flag)
1287836SJohn.Forte@Sun.COM {
1297836SJohn.Forte@Sun.COM 	int rval;
1307836SJohn.Forte@Sun.COM 
1317836SJohn.Forte@Sun.COM 	rval = _sd_write(buf, fba_pos, fba_len, flag);
1327836SJohn.Forte@Sun.COM 	return (rval == NSC_HIT ? NSC_DONE : rval);
1337836SJohn.Forte@Sun.COM }
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM #define	_sd_allocate_buf _trk_allocate_buf
1367836SJohn.Forte@Sun.COM #define	_sd_write	 _sim_write
1377836SJohn.Forte@Sun.COM 
1387836SJohn.Forte@Sun.COM /*
1397836SJohn.Forte@Sun.COM  * INF SD daemon global data
1407836SJohn.Forte@Sun.COM  */
1417836SJohn.Forte@Sun.COM 
1427836SJohn.Forte@Sun.COM volatile int	test_created;
1437836SJohn.Forte@Sun.COM static int	_sd_daemon_created;
1447836SJohn.Forte@Sun.COM static int 	_sd_num_daemons;
1457836SJohn.Forte@Sun.COM 
1467836SJohn.Forte@Sun.COM static struct gld {
1477836SJohn.Forte@Sun.COM 	volatile int type;
1487836SJohn.Forte@Sun.COM 	volatile int loop;
1497836SJohn.Forte@Sun.COM 	volatile int seed;
1507836SJohn.Forte@Sun.COM 	volatile int asleep;
1517836SJohn.Forte@Sun.COM 	kcondvar_t blk;
1527836SJohn.Forte@Sun.COM } gld[MAX_TDAEMONS];
1537836SJohn.Forte@Sun.COM 
1547836SJohn.Forte@Sun.COM /*
1557836SJohn.Forte@Sun.COM  * _sdbc_tdaemon_load: cache is being loaded, initialize any global state that
1567836SJohn.Forte@Sun.COM  * isn't configurable (lock/sv's).
1577836SJohn.Forte@Sun.COM  */
1587836SJohn.Forte@Sun.COM int
_sdbc_tdaemon_load(void)1597836SJohn.Forte@Sun.COM _sdbc_tdaemon_load(void)
1607836SJohn.Forte@Sun.COM {
1617836SJohn.Forte@Sun.COM 	int i;
1627836SJohn.Forte@Sun.COM 
1637836SJohn.Forte@Sun.COM 	for (i = 0; i < MAX_TDAEMONS; i++)
1647836SJohn.Forte@Sun.COM 		cv_init(&gld[i].blk, NULL, CV_DRIVER, NULL);
1657836SJohn.Forte@Sun.COM 
1667836SJohn.Forte@Sun.COM 	mutex_init(&tdaemon_lock, NULL, MUTEX_DRIVER, NULL);
1677836SJohn.Forte@Sun.COM 	cv_init(&_wait_daemons, NULL, CV_DRIVER, NULL);
1687836SJohn.Forte@Sun.COM 
1697836SJohn.Forte@Sun.COM 	return (0);
1707836SJohn.Forte@Sun.COM }
1717836SJohn.Forte@Sun.COM /*
1727836SJohn.Forte@Sun.COM  * _sdbc_tdaemon_unload: cache is being unloaded.
1737836SJohn.Forte@Sun.COM  */
1747836SJohn.Forte@Sun.COM void
_sdbc_tdaemon_unload(void)1757836SJohn.Forte@Sun.COM _sdbc_tdaemon_unload(void)
1767836SJohn.Forte@Sun.COM {
1777836SJohn.Forte@Sun.COM 	int i;
1787836SJohn.Forte@Sun.COM 
1797836SJohn.Forte@Sun.COM 	for (i = 0; i < MAX_TDAEMONS; i++) {
1807836SJohn.Forte@Sun.COM 		cv_destroy(&gld[i].blk);
1817836SJohn.Forte@Sun.COM 	}
1827836SJohn.Forte@Sun.COM 
1837836SJohn.Forte@Sun.COM 	mutex_destroy(&tdaemon_lock);
1847836SJohn.Forte@Sun.COM 	cv_destroy(&_wait_daemons);
1857836SJohn.Forte@Sun.COM 
1867836SJohn.Forte@Sun.COM }
1877836SJohn.Forte@Sun.COM 
1887836SJohn.Forte@Sun.COM /*
1897836SJohn.Forte@Sun.COM  * _sdbc_tdaemon_configure: configure the desired number of test daemons.
1907836SJohn.Forte@Sun.COM  */
1917836SJohn.Forte@Sun.COM int
_sdbc_tdaemon_configure(int num)1927836SJohn.Forte@Sun.COM _sdbc_tdaemon_configure(int num)
1937836SJohn.Forte@Sun.COM {
1947836SJohn.Forte@Sun.COM 	int i;
1957836SJohn.Forte@Sun.COM 
1967836SJohn.Forte@Sun.COM 	if (num >= MAX_TDAEMONS)
1977836SJohn.Forte@Sun.COM 		return (-1);
1987836SJohn.Forte@Sun.COM 
1997836SJohn.Forte@Sun.COM 	for (i = 0; i < num; i++) {
200*9093SRamana.Srikanth@Sun.COM 		cv_init(&gld[i].blk, NULL, CV_DRIVER, NULL);
2017836SJohn.Forte@Sun.COM 	}
2027836SJohn.Forte@Sun.COM 	mutex_enter(&tdaemon_lock);
2037836SJohn.Forte@Sun.COM 	test_created = 1;
2047836SJohn.Forte@Sun.COM 	test_stop = 0;
2057836SJohn.Forte@Sun.COM 	_sd_num_daemons = 0;
2067836SJohn.Forte@Sun.COM 	mutex_exit(&tdaemon_lock);
2077836SJohn.Forte@Sun.COM 
2087836SJohn.Forte@Sun.COM 	mutex_enter(&_sd_cache_lock);
2097836SJohn.Forte@Sun.COM 	if (_sd_daemon_created == 1) {
2107836SJohn.Forte@Sun.COM 		mutex_exit(&_sd_cache_lock);
2117836SJohn.Forte@Sun.COM 		return (-1);
2127836SJohn.Forte@Sun.COM 	}
2137836SJohn.Forte@Sun.COM 	_sd_daemon_created = 1;
2147836SJohn.Forte@Sun.COM 	mutex_exit(&_sd_cache_lock);
2157836SJohn.Forte@Sun.COM 
2167836SJohn.Forte@Sun.COM 	for (i = 0; i < num; i++) {
2177836SJohn.Forte@Sun.COM 		(void) nsc_create_process(
218*9093SRamana.Srikanth@Sun.COM 		    (void (*)(void *))_sd_idle_daemon, 0, FALSE);
2197836SJohn.Forte@Sun.COM 	}
2207836SJohn.Forte@Sun.COM 
2217836SJohn.Forte@Sun.COM #ifdef DEBUG
2227836SJohn.Forte@Sun.COM 	if (num)
223*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!Starting %d SDBC test daemon(s).", num);
2247836SJohn.Forte@Sun.COM #endif
2257836SJohn.Forte@Sun.COM 	return (0);
2267836SJohn.Forte@Sun.COM }
2277836SJohn.Forte@Sun.COM 
2287836SJohn.Forte@Sun.COM void
_sdbc_tdaemon_deconfigure(void)2297836SJohn.Forte@Sun.COM _sdbc_tdaemon_deconfigure(void)
2307836SJohn.Forte@Sun.COM {
2317836SJohn.Forte@Sun.COM 	int i, running, retry = 30;
2327836SJohn.Forte@Sun.COM 
2337836SJohn.Forte@Sun.COM 	if (_sd_num_daemons) {
2347836SJohn.Forte@Sun.COM 		_sd_daemon_created = 0;
2357836SJohn.Forte@Sun.COM 
2367836SJohn.Forte@Sun.COM 		mutex_enter(&tdaemon_lock);
2377836SJohn.Forte@Sun.COM 		test_created = 0;
2387836SJohn.Forte@Sun.COM 		test_stop = 1;
2397836SJohn.Forte@Sun.COM 		mutex_exit(&tdaemon_lock);
2407836SJohn.Forte@Sun.COM 
2417836SJohn.Forte@Sun.COM 		wakeup_all_tdaemons();
2427836SJohn.Forte@Sun.COM 		while (retry--) {
2437836SJohn.Forte@Sun.COM 			delay(HZ);
2447836SJohn.Forte@Sun.COM 			running = 0;
2457836SJohn.Forte@Sun.COM 			for (i = 0; i < _sd_num_daemons; i++)
2467836SJohn.Forte@Sun.COM 				if (daemon_awake(i))
2477836SJohn.Forte@Sun.COM 					running++;
2487836SJohn.Forte@Sun.COM 			if (running == 0) break;
2497836SJohn.Forte@Sun.COM 		}
2507836SJohn.Forte@Sun.COM 	}
2517836SJohn.Forte@Sun.COM 	for (i = 0; i < MAX_CD_STS; i++) {
2527836SJohn.Forte@Sun.COM 		cv_destroy(&cd_test_sts[i].cd_blk);
2537836SJohn.Forte@Sun.COM 		cd_test_sts[i].inited = 0;
2547836SJohn.Forte@Sun.COM 	}
2557836SJohn.Forte@Sun.COM 	_sd_num_daemons = 0;
2567836SJohn.Forte@Sun.COM }
2577836SJohn.Forte@Sun.COM 
2587836SJohn.Forte@Sun.COM 
2597836SJohn.Forte@Sun.COM int sind = 0;
2607836SJohn.Forte@Sun.COM 
2617836SJohn.Forte@Sun.COM /*
2627836SJohn.Forte@Sun.COM  * Globals to change test parameters - Initially added for tests written
2637836SJohn.Forte@Sun.COM  * by Ajay
2647836SJohn.Forte@Sun.COM  */
2657836SJohn.Forte@Sun.COM #ifdef SD_TDAEMON_DEBUG
2667836SJohn.Forte@Sun.COM struct statis {
2677836SJohn.Forte@Sun.COM 	int cd;
2687836SJohn.Forte@Sun.COM 	nsc_size_t len;
2697836SJohn.Forte@Sun.COM 	nsc_off_t offset;
2707836SJohn.Forte@Sun.COM 	int type;
2717836SJohn.Forte@Sun.COM } statis[4000];
2727836SJohn.Forte@Sun.COM 
2737836SJohn.Forte@Sun.COM #define	add_statis(c, l, o, t) (statis[sind].cd = (c), \
2747836SJohn.Forte@Sun.COM 				statis[sind].len = (l), \
2757836SJohn.Forte@Sun.COM 				statis[sind].offset = (o), \
2767836SJohn.Forte@Sun.COM 				statis[sind].type = (t), sind++)
2777836SJohn.Forte@Sun.COM int
statis_upd(caddr_t adr)2787836SJohn.Forte@Sun.COM statis_upd(caddr_t adr)
2797836SJohn.Forte@Sun.COM {
2807836SJohn.Forte@Sun.COM 	(void) copyout(statis, adr, sizeof (struct statis) * sind);
2817836SJohn.Forte@Sun.COM 	return (sind);
2827836SJohn.Forte@Sun.COM }
2837836SJohn.Forte@Sun.COM #endif /* SD_TDAEMON_DEBUG */
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM static int
daemon_awake(int i)2867836SJohn.Forte@Sun.COM daemon_awake(int i)
2877836SJohn.Forte@Sun.COM {
2887836SJohn.Forte@Sun.COM 	if (gld[i].asleep == 2)
2897836SJohn.Forte@Sun.COM 		return (1);
2907836SJohn.Forte@Sun.COM 	return (0);
2917836SJohn.Forte@Sun.COM }
2927836SJohn.Forte@Sun.COM 
2937836SJohn.Forte@Sun.COM static int
daemon_nexist(int i)2947836SJohn.Forte@Sun.COM daemon_nexist(int i)
2957836SJohn.Forte@Sun.COM {
2967836SJohn.Forte@Sun.COM 	if (gld[i].asleep == 0)
2977836SJohn.Forte@Sun.COM 		return (1);
2987836SJohn.Forte@Sun.COM 	return (0);
2997836SJohn.Forte@Sun.COM }
3007836SJohn.Forte@Sun.COM 
3017836SJohn.Forte@Sun.COM static void
daemon_wakeup(int i)3027836SJohn.Forte@Sun.COM daemon_wakeup(int i)
3037836SJohn.Forte@Sun.COM {
3047836SJohn.Forte@Sun.COM #ifdef _SD_DEBUG
305*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_NOTE, "!unblocking %d %x", i, gld[i].blk);
3067836SJohn.Forte@Sun.COM #endif
3077836SJohn.Forte@Sun.COM 	mutex_enter(&tdaemon_lock);
3087836SJohn.Forte@Sun.COM 	cv_broadcast(&gld[i].blk);
3097836SJohn.Forte@Sun.COM 	mutex_exit(&tdaemon_lock);
3107836SJohn.Forte@Sun.COM }
3117836SJohn.Forte@Sun.COM 
3127836SJohn.Forte@Sun.COM 
3137836SJohn.Forte@Sun.COM static void
wakeup_all_tdaemons(void)3147836SJohn.Forte@Sun.COM wakeup_all_tdaemons(void)
3157836SJohn.Forte@Sun.COM {
3167836SJohn.Forte@Sun.COM 	int i;
3177836SJohn.Forte@Sun.COM 
3187836SJohn.Forte@Sun.COM 	for (i = 0; i < _sd_num_daemons; i++)
3197836SJohn.Forte@Sun.COM 		daemon_wakeup(i);
3207836SJohn.Forte@Sun.COM }
3217836SJohn.Forte@Sun.COM 
3227836SJohn.Forte@Sun.COM 
3237836SJohn.Forte@Sun.COM static void
_sd_idle_daemon(void)3247836SJohn.Forte@Sun.COM _sd_idle_daemon(void)
3257836SJohn.Forte@Sun.COM {
3267836SJohn.Forte@Sun.COM 	int who;	/* id of this daemon */
3277836SJohn.Forte@Sun.COM 
3287836SJohn.Forte@Sun.COM 	mutex_enter(&_sd_cache_lock);
3297836SJohn.Forte@Sun.COM 	_sd_cache_dem_cnt++;
3307836SJohn.Forte@Sun.COM 	who = _sd_num_daemons++;
3317836SJohn.Forte@Sun.COM 	mutex_exit(&_sd_cache_lock);
3327836SJohn.Forte@Sun.COM 
3337836SJohn.Forte@Sun.COM 	/* CONSTCOND */
3347836SJohn.Forte@Sun.COM 	while (1) {
3357836SJohn.Forte@Sun.COM 		mutex_enter(&tdaemon_lock);
3367836SJohn.Forte@Sun.COM 		gld[who].asleep = 1;
3377836SJohn.Forte@Sun.COM #ifdef DEBUG
338*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!%d daemon: sleeping %p", who,
3397836SJohn.Forte@Sun.COM 		    (void *)&gld[who].blk);
3407836SJohn.Forte@Sun.COM #endif
3417836SJohn.Forte@Sun.COM 
3427836SJohn.Forte@Sun.COM 		cv_signal(&_wait_daemons);
3437836SJohn.Forte@Sun.COM 		if (test_created == 0) {
3447836SJohn.Forte@Sun.COM 			gld[who].asleep = 0;
3457836SJohn.Forte@Sun.COM 			mutex_exit(&tdaemon_lock);
3467836SJohn.Forte@Sun.COM 			mutex_enter(&_sd_cache_lock);
3477836SJohn.Forte@Sun.COM 			_sd_cache_dem_cnt--;
3487836SJohn.Forte@Sun.COM 			mutex_exit(&_sd_cache_lock);
3497836SJohn.Forte@Sun.COM 			return;
3507836SJohn.Forte@Sun.COM 		} else {
3517836SJohn.Forte@Sun.COM 			cv_wait(&gld[who].blk, &tdaemon_lock);
3527836SJohn.Forte@Sun.COM 			mutex_exit(&tdaemon_lock);
3537836SJohn.Forte@Sun.COM 		}
3547836SJohn.Forte@Sun.COM 
3557836SJohn.Forte@Sun.COM 		_sd_print(0, "%d daemon awake type %d loop %d seed %d",
3567836SJohn.Forte@Sun.COM 		    who, gld[who].type, gld[who].loop, GET_SEED(who));
3577836SJohn.Forte@Sun.COM 
3587836SJohn.Forte@Sun.COM 		if (test_created == 0) {
3597836SJohn.Forte@Sun.COM 			gld[who].asleep = 0;
3607836SJohn.Forte@Sun.COM 			mutex_enter(&_sd_cache_lock);
3617836SJohn.Forte@Sun.COM 			_sd_cache_dem_cnt--;
3627836SJohn.Forte@Sun.COM 			mutex_exit(&_sd_cache_lock);
3637836SJohn.Forte@Sun.COM 			return;
3647836SJohn.Forte@Sun.COM 		}
3657836SJohn.Forte@Sun.COM 		gld[who].asleep = 2;
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 		switch (gld[who].type) {
3687836SJohn.Forte@Sun.COM 
3697836SJohn.Forte@Sun.COM 		case 210:
3707836SJohn.Forte@Sun.COM 			test_dma_loop(gld[who].loop, gld[who].seed);
3717836SJohn.Forte@Sun.COM 			break;
3727836SJohn.Forte@Sun.COM 		case 323:
3737836SJohn.Forte@Sun.COM 			_sd_direct_test(who, gld[who].loop, GET_SEED(who), 0);
3747836SJohn.Forte@Sun.COM 			break;
3757836SJohn.Forte@Sun.COM 
3767836SJohn.Forte@Sun.COM 		case 350:
3777836SJohn.Forte@Sun.COM 			_sd_test_rwloop_seq(who, gld[who].loop, GET_SEED(who),
3787836SJohn.Forte@Sun.COM 			    1);
3797836SJohn.Forte@Sun.COM 			break;
3807836SJohn.Forte@Sun.COM 		case 351:
3817836SJohn.Forte@Sun.COM 			_sd_test_rwloop_seq(who, gld[who].loop, GET_SEED(who),
3827836SJohn.Forte@Sun.COM 			    0);
3837836SJohn.Forte@Sun.COM 			break;
3847836SJohn.Forte@Sun.COM 
3857836SJohn.Forte@Sun.COM #if 0
3867836SJohn.Forte@Sun.COM 		case 400:
3877836SJohn.Forte@Sun.COM 			if (gld[who].loop >= 6)
3887836SJohn.Forte@Sun.COM 				numdevs = gld[who].loop;
3897836SJohn.Forte@Sun.COM 			break;
3907836SJohn.Forte@Sun.COM #endif
3917836SJohn.Forte@Sun.COM 		default:
392*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!%d daemon %d type inval\n", who,
3937836SJohn.Forte@Sun.COM 			    gld[who].type);
3947836SJohn.Forte@Sun.COM 			break;
3957836SJohn.Forte@Sun.COM 		}
3967836SJohn.Forte@Sun.COM 		if (test_created == 0) {
3977836SJohn.Forte@Sun.COM 			gld[who].asleep = 0;
3987836SJohn.Forte@Sun.COM 			mutex_enter(&_sd_cache_lock);
3997836SJohn.Forte@Sun.COM 			_sd_cache_dem_cnt--;
4007836SJohn.Forte@Sun.COM 			mutex_exit(&_sd_cache_lock);
4017836SJohn.Forte@Sun.COM 			return;
4027836SJohn.Forte@Sun.COM 		}
4037836SJohn.Forte@Sun.COM 	}
4047836SJohn.Forte@Sun.COM }
4057836SJohn.Forte@Sun.COM 
4067836SJohn.Forte@Sun.COM 
4077836SJohn.Forte@Sun.COM static void
_td_attach_cd(int cd)4087836SJohn.Forte@Sun.COM _td_attach_cd(int cd)
4097836SJohn.Forte@Sun.COM {
4107836SJohn.Forte@Sun.COM 	(void) nsc_reserve(_sd_cache_files[cd].cd_rawfd, NSC_MULTI);
4117836SJohn.Forte@Sun.COM }
4127836SJohn.Forte@Sun.COM 
4137836SJohn.Forte@Sun.COM 
4147836SJohn.Forte@Sun.COM static void
_td_detach_cd(int cd)4157836SJohn.Forte@Sun.COM _td_detach_cd(int cd)
4167836SJohn.Forte@Sun.COM {
4177836SJohn.Forte@Sun.COM 	nsc_release(_sd_cache_files[cd].cd_rawfd);
4187836SJohn.Forte@Sun.COM }
4197836SJohn.Forte@Sun.COM 
4207836SJohn.Forte@Sun.COM 
4217836SJohn.Forte@Sun.COM int
_sd_test_start(void * args,int * rvp)4227836SJohn.Forte@Sun.COM _sd_test_start(void *args, int *rvp)
4237836SJohn.Forte@Sun.COM {
4247836SJohn.Forte@Sun.COM 
4257836SJohn.Forte@Sun.COM 	register struct a {
4267836SJohn.Forte@Sun.COM 		long num;
4277836SJohn.Forte@Sun.COM 		long type;
4287836SJohn.Forte@Sun.COM 		long loop;
4297836SJohn.Forte@Sun.COM 		long from;
4307836SJohn.Forte@Sun.COM 		long seed;
4317836SJohn.Forte@Sun.COM 	} *uap = (struct a *)args;
4327836SJohn.Forte@Sun.COM 
4337836SJohn.Forte@Sun.COM 	*rvp = _fork_test_daemon(uap->num, uap->type, uap->loop,
434*9093SRamana.Srikanth@Sun.COM 	    uap->from, uap->seed);
4357836SJohn.Forte@Sun.COM 
4367836SJohn.Forte@Sun.COM 	return (0);
4377836SJohn.Forte@Sun.COM }
4387836SJohn.Forte@Sun.COM 
4397836SJohn.Forte@Sun.COM static int
test_control(int typ,int cd,nsc_off_t fba_pos,nsc_size_t fba_len)4407836SJohn.Forte@Sun.COM test_control(int typ, int cd, nsc_off_t fba_pos, nsc_size_t fba_len)
4417836SJohn.Forte@Sun.COM /*
4427836SJohn.Forte@Sun.COM  * test_control - perform control operations outside of the range
4437836SJohn.Forte@Sun.COM  * of a test. This is typically called before/after a series of
4447836SJohn.Forte@Sun.COM  * tests to either check a result or to setup/free a device.
4457836SJohn.Forte@Sun.COM  */
4467836SJohn.Forte@Sun.COM {
4477836SJohn.Forte@Sun.COM 	int rc = 0;
4487836SJohn.Forte@Sun.COM 
4497836SJohn.Forte@Sun.COM 	if ((cd < 0) || (cd >= sdbc_max_devs))
4507836SJohn.Forte@Sun.COM 		return (-1);
4517836SJohn.Forte@Sun.COM 	switch (typ) {
4527836SJohn.Forte@Sun.COM 	case 1:
4537836SJohn.Forte@Sun.COM 		rc = _sdbc_io_attach_cd((blind_t)(unsigned long)cd);
454*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!_sdbc_io_attach_cd(%d): %d", cd, rc);
4557836SJohn.Forte@Sun.COM 		break;
4567836SJohn.Forte@Sun.COM 	case 2:
4577836SJohn.Forte@Sun.COM 		rc = _sdbc_io_detach_cd((blind_t)(unsigned long)cd);
458*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!_sdbc_io_detach_cd(%d): %d", cd, rc);
4597836SJohn.Forte@Sun.COM 		break;
4607836SJohn.Forte@Sun.COM 	case 3:
4617836SJohn.Forte@Sun.COM 		_test_async_fail = _sd_cache_files[cd].cd_crdev;
462*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!async fail dev %lu (cd=%d)",
463*9093SRamana.Srikanth@Sun.COM 		    _test_async_fail, cd);
4647836SJohn.Forte@Sun.COM 		break;
4657836SJohn.Forte@Sun.COM 	case 4:
4667836SJohn.Forte@Sun.COM 		_test_async_fail = 0;
467*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!async fail cleared");
4687836SJohn.Forte@Sun.COM 		break;
4697836SJohn.Forte@Sun.COM #if 0
4707836SJohn.Forte@Sun.COM 	case 5:
4717836SJohn.Forte@Sun.COM 		_trk_alloc_flag = NSC_PINNABLE;
4727836SJohn.Forte@Sun.COM 		break;
4737836SJohn.Forte@Sun.COM 	case 6:
4747836SJohn.Forte@Sun.COM 		_trk_alloc_flag = 0;
4757836SJohn.Forte@Sun.COM 		break;
4767836SJohn.Forte@Sun.COM #endif
4777836SJohn.Forte@Sun.COM 	case 7:
4787836SJohn.Forte@Sun.COM 		rc = _sd_get_pinned((blind_t)(unsigned long)cd);
479*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!get_pinned(%d): %d", cd, rc);
4807836SJohn.Forte@Sun.COM 		break;
4817836SJohn.Forte@Sun.COM 	case 8:
4827836SJohn.Forte@Sun.COM 		rc = _sd_discard_pinned((blind_t)(unsigned long)cd, fba_pos,
4837836SJohn.Forte@Sun.COM 		    fba_len);
484*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!discard_pinned(%d,%" NSC_SZFMT ",%" NSC_SZFMT
4857836SJohn.Forte@Sun.COM 		    "): %d", cd, fba_pos, fba_len, rc);
4867836SJohn.Forte@Sun.COM 		break;
4877836SJohn.Forte@Sun.COM 	default:
488*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!cache device command %d invalid\n", typ);
4897836SJohn.Forte@Sun.COM 	}
4907836SJohn.Forte@Sun.COM 	return (rc);
4917836SJohn.Forte@Sun.COM }
4927836SJohn.Forte@Sun.COM 
4937836SJohn.Forte@Sun.COM 
4947836SJohn.Forte@Sun.COM /*
4957836SJohn.Forte@Sun.COM  * _fork_sd_daemon(): Fork an nunix process that periodically flushes the
4967836SJohn.Forte@Sun.COM  *                    raw device buffer cache
4977836SJohn.Forte@Sun.COM  */
4987836SJohn.Forte@Sun.COM 
4997836SJohn.Forte@Sun.COM static int
_fork_test_daemon(int num_disks,int test_typ,int loop_cnt,int from,int seed)5007836SJohn.Forte@Sun.COM _fork_test_daemon(int num_disks, int test_typ, int loop_cnt, int from, int seed)
5017836SJohn.Forte@Sun.COM {
5027836SJohn.Forte@Sun.COM 	int i;
5037836SJohn.Forte@Sun.COM 	int type;
5047836SJohn.Forte@Sun.COM 	int dowait = 0, verify = 0;
5057836SJohn.Forte@Sun.COM 
5067836SJohn.Forte@Sun.COM 	if (num_disks == -1) {
5077836SJohn.Forte@Sun.COM 		return (test_control(test_typ, loop_cnt, from, seed));
5087836SJohn.Forte@Sun.COM 	}
5097836SJohn.Forte@Sun.COM 
5107836SJohn.Forte@Sun.COM 	type = test_typ;
5117836SJohn.Forte@Sun.COM 	cmn_err(CE_NOTE,
512*9093SRamana.Srikanth@Sun.COM 	    "!sd_test %d %d %d %d %d", num_disks, type, loop_cnt, from, seed);
5137836SJohn.Forte@Sun.COM 	if (type == 100) {
5147836SJohn.Forte@Sun.COM 		test_stop = 1;
5157836SJohn.Forte@Sun.COM 		return (0);
5167836SJohn.Forte@Sun.COM 	}
5177836SJohn.Forte@Sun.COM 
5187836SJohn.Forte@Sun.COM 	if (type == 99) {
5197836SJohn.Forte@Sun.COM 		/* Set some parameters for other tests */
5207836SJohn.Forte@Sun.COM 		switch (num_disks) {
5217836SJohn.Forte@Sun.COM 			/* Params set for this test */
5227836SJohn.Forte@Sun.COM #if 0
5237836SJohn.Forte@Sun.COM 			case 302 :
5247836SJohn.Forte@Sun.COM 				_sd_write_len = loop_cnt;
5257836SJohn.Forte@Sun.COM 				break;
5267836SJohn.Forte@Sun.COM 			case 303 :
5277836SJohn.Forte@Sun.COM 				_sd_write_len = loop_cnt;
5287836SJohn.Forte@Sun.COM 				break;
5297836SJohn.Forte@Sun.COM 			case 304 :
5307836SJohn.Forte@Sun.COM 				_sd_trk_zero = loop_cnt;
5317836SJohn.Forte@Sun.COM 				_sd_trk_size = from;
5327836SJohn.Forte@Sun.COM 				break;
5337836SJohn.Forte@Sun.COM 			case 305 :
5347836SJohn.Forte@Sun.COM 				_sd_min_blks = loop_cnt;
5357836SJohn.Forte@Sun.COM 				_sd_max_blks = from;
5367836SJohn.Forte@Sun.COM 				break;
5377836SJohn.Forte@Sun.COM #endif
5387836SJohn.Forte@Sun.COM 			default :
5397836SJohn.Forte@Sun.COM 				cmn_err(CE_WARN,
540*9093SRamana.Srikanth@Sun.COM 				    "!Usage : sd_test <test_num> 99"
5417836SJohn.Forte@Sun.COM 				    " <param1> <param2> <param3>");
5427836SJohn.Forte@Sun.COM 				break;
5437836SJohn.Forte@Sun.COM 		}
5447836SJohn.Forte@Sun.COM 		return (0);
5457836SJohn.Forte@Sun.COM 	}		/* type == 99 */
5467836SJohn.Forte@Sun.COM 
5477836SJohn.Forte@Sun.COM 	if (type > 1000) {
5487836SJohn.Forte@Sun.COM 		dowait = 1;
5497836SJohn.Forte@Sun.COM 		type -= 1000;
5507836SJohn.Forte@Sun.COM 	}
5517836SJohn.Forte@Sun.COM 	if (type > 1000) {
5527836SJohn.Forte@Sun.COM 		verify = 1;
5537836SJohn.Forte@Sun.COM 		type -= 1000;
5547836SJohn.Forte@Sun.COM 	}
5557836SJohn.Forte@Sun.COM 
5567836SJohn.Forte@Sun.COM again:
5577836SJohn.Forte@Sun.COM 	set_parameters();
5587836SJohn.Forte@Sun.COM 
5597836SJohn.Forte@Sun.COM 	for (i = from; i < (from+num_disks); i++) {
5607836SJohn.Forte@Sun.COM 		if (daemon_awake(i)) {
561*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!Daemon %d awake!?", i);
5627836SJohn.Forte@Sun.COM 			return (-1);
5637836SJohn.Forte@Sun.COM 		}
5647836SJohn.Forte@Sun.COM 		if (daemon_nexist(i)) {
565*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!Daemon %d nexist!?", i);
5667836SJohn.Forte@Sun.COM 			return (-1);
5677836SJohn.Forte@Sun.COM 		}
5687836SJohn.Forte@Sun.COM 
5697836SJohn.Forte@Sun.COM 		gld[i].type = type;
5707836SJohn.Forte@Sun.COM 		gld[i].loop = loop_cnt;
5717836SJohn.Forte@Sun.COM 		gld[i].seed = seed;
5727836SJohn.Forte@Sun.COM 		daemon_wakeup(i);
5737836SJohn.Forte@Sun.COM 	}
574*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_CONT, "!%d daemons woken (test %d)\n", num_disks, type);
5757836SJohn.Forte@Sun.COM 	if (num_disks <= 0)
5767836SJohn.Forte@Sun.COM 		return (0);
5777836SJohn.Forte@Sun.COM 
5787836SJohn.Forte@Sun.COM 	if (dowait) {
5797836SJohn.Forte@Sun.COM 	wait:
5807836SJohn.Forte@Sun.COM 		mutex_enter(&tdaemon_lock);
5817836SJohn.Forte@Sun.COM 		if (!cv_wait_sig(&_wait_daemons, &tdaemon_lock)) {
5827836SJohn.Forte@Sun.COM 			mutex_exit(&tdaemon_lock);
5837836SJohn.Forte@Sun.COM 			test_stop = 1;
584*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!Interrupt: stopping tests");
5857836SJohn.Forte@Sun.COM 			return (-1); /* interrupt */
5867836SJohn.Forte@Sun.COM 		}
5877836SJohn.Forte@Sun.COM 		mutex_exit(&tdaemon_lock);
5887836SJohn.Forte@Sun.COM 
5897836SJohn.Forte@Sun.COM 		/* wait for all to stop */
5907836SJohn.Forte@Sun.COM 		if (test_stop)
5917836SJohn.Forte@Sun.COM 			return (-1);
5927836SJohn.Forte@Sun.COM 		for (i = from; i < (from+num_disks); i++) {
5937836SJohn.Forte@Sun.COM 			if (daemon_awake(i))
5947836SJohn.Forte@Sun.COM 				goto wait;
5957836SJohn.Forte@Sun.COM 		}
5967836SJohn.Forte@Sun.COM 	}
5977836SJohn.Forte@Sun.COM 	if (verify) {
5987836SJohn.Forte@Sun.COM 		verify = 0;
5997836SJohn.Forte@Sun.COM 		type++;		/* next test */
6007836SJohn.Forte@Sun.COM 		goto again;
6017836SJohn.Forte@Sun.COM 	}
6027836SJohn.Forte@Sun.COM 	return (0);
6037836SJohn.Forte@Sun.COM }
6047836SJohn.Forte@Sun.COM 
6057836SJohn.Forte@Sun.COM int
_sd_test_end(void)6067836SJohn.Forte@Sun.COM _sd_test_end(void)
6077836SJohn.Forte@Sun.COM {
6087836SJohn.Forte@Sun.COM 	test_created = 0;
6097836SJohn.Forte@Sun.COM 	test_stop = 1;
6107836SJohn.Forte@Sun.COM 	return (0);
6117836SJohn.Forte@Sun.COM }
6127836SJohn.Forte@Sun.COM 
6137836SJohn.Forte@Sun.COM int
_sd_test_init(void * args)6147836SJohn.Forte@Sun.COM _sd_test_init(void *args)
6157836SJohn.Forte@Sun.COM {
6167836SJohn.Forte@Sun.COM 	register struct a {
6177836SJohn.Forte@Sun.COM 		caddr_t addr;
6187836SJohn.Forte@Sun.COM 		long ar;
6197836SJohn.Forte@Sun.COM 		long len;
6207836SJohn.Forte@Sun.COM 		long tsize;
6217836SJohn.Forte@Sun.COM 		long flag;
6227836SJohn.Forte@Sun.COM 	} *uap = (struct a *)args;
6237836SJohn.Forte@Sun.COM 
6247836SJohn.Forte@Sun.COM 	if (copyin(uap->addr, devarray[uap->ar], uap->len)) {
6257836SJohn.Forte@Sun.COM 		return (EFAULT);
6267836SJohn.Forte@Sun.COM 	}
6277836SJohn.Forte@Sun.COM 	dev_tsize[uap->ar] = (uap->tsize < 48) ? 48 : uap->tsize;
6287836SJohn.Forte@Sun.COM 	dev_flag[uap->ar] = uap->flag;
6297836SJohn.Forte@Sun.COM 	return (0);
6307836SJohn.Forte@Sun.COM }
6317836SJohn.Forte@Sun.COM 
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM typedef struct io_type {
6347836SJohn.Forte@Sun.COM 	int cd, tsize;
6357836SJohn.Forte@Sun.COM 	_sd_buf_handle_t *wbuf, *rbuf;
6367836SJohn.Forte@Sun.COM 	int len, len2, rnet, wnet;
6377836SJohn.Forte@Sun.COM 	int trk_num, trk_off;
6387836SJohn.Forte@Sun.COM 	int offset, boff;
6397836SJohn.Forte@Sun.COM 	char test_pattern;
6407836SJohn.Forte@Sun.COM } infnsc_io_t;
6417836SJohn.Forte@Sun.COM 
6427836SJohn.Forte@Sun.COM /* static spinlock_t INFSD_iolock = { SLK_IFS_SRVR, 0 }; */
6437836SJohn.Forte@Sun.COM #define	_INFSD_TRK_SIZE() (64*1024)
6447836SJohn.Forte@Sun.COM #define	_INFSD_BUF_ALIGN 512	/* Each read/write should be 512 aligned */
6457836SJohn.Forte@Sun.COM 
6467836SJohn.Forte@Sun.COM /*
6477836SJohn.Forte@Sun.COM  * _sd_test_rwloop_seq(i,loops, seed, forw):
6487836SJohn.Forte@Sun.COM  *
6497836SJohn.Forte@Sun.COM  * Sequential I/O test. Writes track records sequentially, either forwards
6507836SJohn.Forte@Sun.COM  * or backwards (forw = 1 or forw = 0), writing a fixed pattern with a
6517836SJohn.Forte@Sun.COM  * few unique bytes depending on loop id. Then reads back, checking
6527836SJohn.Forte@Sun.COM  * for data consistency.
6537836SJohn.Forte@Sun.COM  */
6547836SJohn.Forte@Sun.COM 
6557836SJohn.Forte@Sun.COM /* ARGSUSED */
6567836SJohn.Forte@Sun.COM static void
_sd_test_rwloop_seq(int i,int loops,int seed,int forw)6577836SJohn.Forte@Sun.COM _sd_test_rwloop_seq(int i, int loops, int seed, int forw)
6587836SJohn.Forte@Sun.COM {
6597836SJohn.Forte@Sun.COM 	int cd;
6607836SJohn.Forte@Sun.COM 	int j, len;
6617836SJohn.Forte@Sun.COM 	nsc_off_t offset;
6627836SJohn.Forte@Sun.COM 	nsc_size_t fsize;
6637836SJohn.Forte@Sun.COM 	int sts;
6647836SJohn.Forte@Sun.COM 	_sd_buf_handle_t *fbuf, *buf;
6657836SJohn.Forte@Sun.COM 
6667836SJohn.Forte@Sun.COM 	if (strlen(devarray[i]) == 0) {
667*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!child %d devarray null", i);
6687836SJohn.Forte@Sun.COM 		return;
6697836SJohn.Forte@Sun.COM 	}
6707836SJohn.Forte@Sun.COM 	if ((cd = _sd_open(devarray[i], dev_flag[i])) < 0) {
671*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Open error %s child %d", devarray[i], i);
6727836SJohn.Forte@Sun.COM 		return;
6737836SJohn.Forte@Sun.COM 	}
6747836SJohn.Forte@Sun.COM 	SET_CD_STATE(cd, i);
6757836SJohn.Forte@Sun.COM 	_td_attach_cd(cd);
6767836SJohn.Forte@Sun.COM 
6777836SJohn.Forte@Sun.COM 	(void) _sd_get_partsize((blind_t)(unsigned long)cd, &fsize);
6787836SJohn.Forte@Sun.COM 	len = 120;
6797836SJohn.Forte@Sun.COM 
6807836SJohn.Forte@Sun.COM 	/*
6817836SJohn.Forte@Sun.COM 	 * Write a base pattern into the first buffer
6827836SJohn.Forte@Sun.COM 	 */
6837836SJohn.Forte@Sun.COM 	fbuf = NULL;
6847836SJohn.Forte@Sun.COM 	offset = 0;
6857836SJohn.Forte@Sun.COM 	sts = _sd_alloc_buf((blind_t)(unsigned long)cd, 0, len, NSC_WRBUF,
6867836SJohn.Forte@Sun.COM 	    &fbuf);
6877836SJohn.Forte@Sun.COM 	if (sts > 0)  {
688*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Buffer alloc failed %d", sts);
6897836SJohn.Forte@Sun.COM 		return;
6907836SJohn.Forte@Sun.COM 	}
6917836SJohn.Forte@Sun.COM 	(void) _sd_copy_pattern_to_handle(fbuf, 0, len);
6927836SJohn.Forte@Sun.COM 	_td_detach_cd(cd);
6937836SJohn.Forte@Sun.COM 
6947836SJohn.Forte@Sun.COM 	offset = 0;
6957836SJohn.Forte@Sun.COM 	for (j = 0; j < loops; j++) {
6967836SJohn.Forte@Sun.COM 		if (test_stop == 1) goto done;
6977836SJohn.Forte@Sun.COM 
6987836SJohn.Forte@Sun.COM 		offset += len;
6997836SJohn.Forte@Sun.COM 		if (offset + len > fsize)
7007836SJohn.Forte@Sun.COM 			break;
7017836SJohn.Forte@Sun.COM 
7027836SJohn.Forte@Sun.COM 		buf = NULL;
7037836SJohn.Forte@Sun.COM 		_td_attach_cd(cd);
7047836SJohn.Forte@Sun.COM 		sts = _sd_alloc_buf((blind_t)(unsigned long)cd, offset, len,
7057836SJohn.Forte@Sun.COM 		    NSC_WRBUF, &buf);
7067836SJohn.Forte@Sun.COM 		if (sts > 0) {
707*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!ch%d getbuf error(WRBUF)%d", i, sts);
7087836SJohn.Forte@Sun.COM 			goto done;
7097836SJohn.Forte@Sun.COM 		}
7107836SJohn.Forte@Sun.COM 		(void) _sd_copy_handle(fbuf, buf, 0, offset, len, j);
7117836SJohn.Forte@Sun.COM 
7127836SJohn.Forte@Sun.COM 		sts = len;
7137836SJohn.Forte@Sun.COM 		while (sts > 0) {
7147836SJohn.Forte@Sun.COM 			if (forw && _sd_hwrite(buf, offset + len - sts,
7157836SJohn.Forte@Sun.COM 			    12, 0) > 0) {
716*9093SRamana.Srikanth@Sun.COM 				cmn_err(CE_WARN, "!ch %d fwwr err", i);
7177836SJohn.Forte@Sun.COM 				test_stop = 1;
7187836SJohn.Forte@Sun.COM 			}
7197836SJohn.Forte@Sun.COM 			sts -= 12;
7207836SJohn.Forte@Sun.COM 			if (!forw && _sd_hwrite(buf, offset + sts, 12, 0) > 0) {
721*9093SRamana.Srikanth@Sun.COM 				cmn_err(CE_WARN, "!ch %d rvwr err", i);
7227836SJohn.Forte@Sun.COM 				test_stop = 1;
7237836SJohn.Forte@Sun.COM 			}
7247836SJohn.Forte@Sun.COM 		}
7257836SJohn.Forte@Sun.COM 		if (sts = _sd_free_buf(buf)) {
726*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!ch %d freebuf error %d", i, sts);
7277836SJohn.Forte@Sun.COM 			goto done;
7287836SJohn.Forte@Sun.COM 		}
7297836SJohn.Forte@Sun.COM 		_td_detach_cd(cd);
7307836SJohn.Forte@Sun.COM 	}
7317836SJohn.Forte@Sun.COM 	offset = 0;
7327836SJohn.Forte@Sun.COM 	for (j = 0; j < loops; j++) {
7337836SJohn.Forte@Sun.COM 		if (test_stop == 1) goto done;
7347836SJohn.Forte@Sun.COM 
7357836SJohn.Forte@Sun.COM 		offset += len;
7367836SJohn.Forte@Sun.COM 		if (offset + len > fsize)
7377836SJohn.Forte@Sun.COM 			break;
7387836SJohn.Forte@Sun.COM 
7397836SJohn.Forte@Sun.COM 		buf = NULL;
7407836SJohn.Forte@Sun.COM 		_td_attach_cd(cd);
7417836SJohn.Forte@Sun.COM 		sts = _sd_alloc_buf((blind_t)(unsigned long)cd, offset, len,
7427836SJohn.Forte@Sun.COM 		    NSC_RDBUF, &buf);
7437836SJohn.Forte@Sun.COM 		if (sts > 0) {
744*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!ch%d getbuf error(WRBUF)%d", i, sts);
7457836SJohn.Forte@Sun.COM 			goto done;
7467836SJohn.Forte@Sun.COM 		}
7477836SJohn.Forte@Sun.COM 		(void) _sd_compare_handle(fbuf, buf, 0, offset, len, j);
7487836SJohn.Forte@Sun.COM 
7497836SJohn.Forte@Sun.COM 		if (sts = _sd_free_buf(buf)) {
750*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!ch %d freebuf error %d", i, sts);
7517836SJohn.Forte@Sun.COM 			goto done;
7527836SJohn.Forte@Sun.COM 		}
7537836SJohn.Forte@Sun.COM 		_td_detach_cd(cd);
7547836SJohn.Forte@Sun.COM 	}
7557836SJohn.Forte@Sun.COM done:
7567836SJohn.Forte@Sun.COM 	if (sts = _sd_free_buf(fbuf))
757*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!child %d freebuf error %d", i, sts);
758*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_NOTE, "!TEST OVER : rwloop_seq_%s() child %d",
7597836SJohn.Forte@Sun.COM 	    forw ? "forw" : "rev", i);
7607836SJohn.Forte@Sun.COM }
7617836SJohn.Forte@Sun.COM 
7627836SJohn.Forte@Sun.COM static int
_sd_copy_pattern_to_handle(_sd_buf_handle_t * handle,nsc_off_t fba_pos,nsc_size_t fba_len)7637836SJohn.Forte@Sun.COM _sd_copy_pattern_to_handle(_sd_buf_handle_t *handle, nsc_off_t fba_pos,
7647836SJohn.Forte@Sun.COM     nsc_size_t fba_len)
7657836SJohn.Forte@Sun.COM {
7667836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_len;	/* FBA len of starting cache block */
7677836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t end_cblk_len;	/* FBA len of ending cache block */
7687836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_off;	/* FBA offset into starting cblock */
7697836SJohn.Forte@Sun.COM 	nsc_size_t cur_fba_len;
7707836SJohn.Forte@Sun.COM 	int i;
7717836SJohn.Forte@Sun.COM 	_sd_cctl_t *cc_ent;
7727836SJohn.Forte@Sun.COM 
7737836SJohn.Forte@Sun.COM 	cc_ent = handle->bh_centry;
7747836SJohn.Forte@Sun.COM 	while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos))
7757836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
7767836SJohn.Forte@Sun.COM 
7777836SJohn.Forte@Sun.COM 	cur_fba_len = fba_len;
7787836SJohn.Forte@Sun.COM 	st_cblk_off = BLK_FBA_OFF(fba_pos);
7797836SJohn.Forte@Sun.COM 	st_cblk_len = (BLK_FBAS - st_cblk_off);
7807836SJohn.Forte@Sun.COM 	if ((nsc_size_t)st_cblk_len >= fba_len) {
7817836SJohn.Forte@Sun.COM 		end_cblk_len = 0;
7827836SJohn.Forte@Sun.COM 		st_cblk_len = (sdbc_cblk_fba_t)fba_len;
7837836SJohn.Forte@Sun.COM 	} else
7847836SJohn.Forte@Sun.COM 		end_cblk_len = BLK_FBA_OFF(fba_pos + fba_len);
7857836SJohn.Forte@Sun.COM 
7867836SJohn.Forte@Sun.COM 	for (i = 0; i < (int)FBA_SIZE(st_cblk_len); i += 4)
7877836SJohn.Forte@Sun.COM 		*((uint_t *)(void *)(cc_ent->cc_data + FBA_SIZE(st_cblk_off) +
7887836SJohn.Forte@Sun.COM 		    i)) = nsc_usec();
7897836SJohn.Forte@Sun.COM 	cur_fba_len -= st_cblk_len;
7907836SJohn.Forte@Sun.COM 	cc_ent = cc_ent->cc_chain;
7917836SJohn.Forte@Sun.COM 
7927836SJohn.Forte@Sun.COM 	while (cur_fba_len > (nsc_size_t)end_cblk_len) {
7937836SJohn.Forte@Sun.COM 		for (i = 0; i < CACHE_BLOCK_SIZE; i += 4) {
7947836SJohn.Forte@Sun.COM 			unsigned int usec = nsc_usec();
7957836SJohn.Forte@Sun.COM 			bcopy(&usec, cc_ent->cc_data + i, 4);
7967836SJohn.Forte@Sun.COM 		}
7977836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
7987836SJohn.Forte@Sun.COM 		cur_fba_len -= BLK_FBAS;
7997836SJohn.Forte@Sun.COM 	}
8007836SJohn.Forte@Sun.COM 	if (cur_fba_len) {
8017836SJohn.Forte@Sun.COM 		for (i = 0; i < (int)FBA_SIZE(end_cblk_len); i += 4) {
8027836SJohn.Forte@Sun.COM 			unsigned int usec = nsc_usec();
8037836SJohn.Forte@Sun.COM 			bcopy(&usec, cc_ent->cc_data + i, 4);
8047836SJohn.Forte@Sun.COM 		}
8057836SJohn.Forte@Sun.COM 	}
8067836SJohn.Forte@Sun.COM 	return (0);
8077836SJohn.Forte@Sun.COM }
8087836SJohn.Forte@Sun.COM 
8097836SJohn.Forte@Sun.COM static int
_sd_copy_handle(_sd_buf_handle_t * handle1,_sd_buf_handle_t * handle2,nsc_off_t fba_pos1,nsc_off_t fba_pos2,nsc_size_t fba_len,int skew)8107836SJohn.Forte@Sun.COM _sd_copy_handle(_sd_buf_handle_t *handle1,
8117836SJohn.Forte@Sun.COM 		_sd_buf_handle_t *handle2,
8127836SJohn.Forte@Sun.COM 		nsc_off_t fba_pos1,
8137836SJohn.Forte@Sun.COM 		nsc_off_t fba_pos2,
8147836SJohn.Forte@Sun.COM 		nsc_size_t fba_len,
8157836SJohn.Forte@Sun.COM 		int skew)
8167836SJohn.Forte@Sun.COM {
8177836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_len;	/* FBA len of starting cache block */
8187836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t end_cblk_len;	/* FBA len of ending cache block */
8197836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_off;	/* FBA offset into starting cblock */
8207836SJohn.Forte@Sun.COM 	nsc_size_t cur_fba_len;
8217836SJohn.Forte@Sun.COM 	_sd_cctl_t *cc_ent, *cc_ent1;
8227836SJohn.Forte@Sun.COM 	unsigned char *skew_word;
8237836SJohn.Forte@Sun.COM 	int skew_count = 0;
8247836SJohn.Forte@Sun.COM 
8257836SJohn.Forte@Sun.COM 	ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
8267836SJohn.Forte@Sun.COM 	ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
8277836SJohn.Forte@Sun.COM 
8287836SJohn.Forte@Sun.COM 	cc_ent = handle1->bh_centry;
8297836SJohn.Forte@Sun.COM 	while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos1))
8307836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
8317836SJohn.Forte@Sun.COM 
8327836SJohn.Forte@Sun.COM 	cc_ent1 = handle2->bh_centry;
8337836SJohn.Forte@Sun.COM 	while (CENTRY_BLK(cc_ent1) != FBA_TO_BLK_NUM(fba_pos2))
8347836SJohn.Forte@Sun.COM 		cc_ent1 = cc_ent1->cc_chain;
8357836SJohn.Forte@Sun.COM 
8367836SJohn.Forte@Sun.COM 
8377836SJohn.Forte@Sun.COM 	if (BLK_FBA_OFF(fba_pos1) != BLK_FBA_OFF(fba_pos2)) {
838*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Cannot copy unaligned handles");
8397836SJohn.Forte@Sun.COM 		return (0);
8407836SJohn.Forte@Sun.COM 	}
8417836SJohn.Forte@Sun.COM 
8427836SJohn.Forte@Sun.COM 	cur_fba_len = fba_len;
8437836SJohn.Forte@Sun.COM 	st_cblk_off = BLK_FBA_OFF(fba_pos1);
8447836SJohn.Forte@Sun.COM 	st_cblk_len = (BLK_FBAS - st_cblk_off);
8457836SJohn.Forte@Sun.COM 	if ((nsc_size_t)st_cblk_len >= fba_len) {
8467836SJohn.Forte@Sun.COM 		end_cblk_len = 0;
8477836SJohn.Forte@Sun.COM 		st_cblk_len = (sdbc_cblk_fba_t)fba_len;
8487836SJohn.Forte@Sun.COM 	} else
8497836SJohn.Forte@Sun.COM 		end_cblk_len = BLK_FBA_OFF(fba_pos1 + fba_len);
8507836SJohn.Forte@Sun.COM 
8517836SJohn.Forte@Sun.COM 	skew_word = cc_ent->cc_data + FBA_SIZE(st_cblk_off);
8527836SJohn.Forte@Sun.COM 	*skew_word = skew | (++skew_count << 24);
8537836SJohn.Forte@Sun.COM 	bcopy(cc_ent->cc_data + FBA_SIZE(st_cblk_off), cc_ent1->cc_data +
8547836SJohn.Forte@Sun.COM 	    FBA_SIZE(st_cblk_off), FBA_SIZE(st_cblk_len));
8557836SJohn.Forte@Sun.COM 	cur_fba_len -= st_cblk_len;
8567836SJohn.Forte@Sun.COM 	cc_ent = cc_ent->cc_chain;
8577836SJohn.Forte@Sun.COM 	cc_ent1 = cc_ent1->cc_chain;
8587836SJohn.Forte@Sun.COM 
8597836SJohn.Forte@Sun.COM 	while (cur_fba_len > (nsc_size_t)end_cblk_len) {
8607836SJohn.Forte@Sun.COM 		skew_word = cc_ent->cc_data;
8617836SJohn.Forte@Sun.COM 		*skew_word = skew | (++skew_count << 24);
8627836SJohn.Forte@Sun.COM 		bcopy(cc_ent->cc_data, cc_ent1->cc_data, CACHE_BLOCK_SIZE);
8637836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
8647836SJohn.Forte@Sun.COM 		cc_ent1 = cc_ent1->cc_chain;
8657836SJohn.Forte@Sun.COM 		cur_fba_len -= BLK_FBAS;
8667836SJohn.Forte@Sun.COM 	}
8677836SJohn.Forte@Sun.COM 	if (cur_fba_len) {
8687836SJohn.Forte@Sun.COM 		skew_word = cc_ent->cc_data;
8697836SJohn.Forte@Sun.COM 		*skew_word = skew | (++skew_count << 24);
8707836SJohn.Forte@Sun.COM 		bcopy(cc_ent->cc_data, cc_ent1->cc_data,
8717836SJohn.Forte@Sun.COM 		    FBA_SIZE(end_cblk_len));
8727836SJohn.Forte@Sun.COM 	}
8737836SJohn.Forte@Sun.COM 	return (0);
8747836SJohn.Forte@Sun.COM }
8757836SJohn.Forte@Sun.COM 
8767836SJohn.Forte@Sun.COM static int
_sd_compare_handle(_sd_buf_handle_t * handle1,_sd_buf_handle_t * handle2,nsc_off_t fba_pos1,nsc_off_t fba_pos2,nsc_size_t fba_len,int skew)8777836SJohn.Forte@Sun.COM _sd_compare_handle(_sd_buf_handle_t *handle1, _sd_buf_handle_t *handle2,
8787836SJohn.Forte@Sun.COM     nsc_off_t fba_pos1, nsc_off_t fba_pos2, nsc_size_t fba_len, int skew)
8797836SJohn.Forte@Sun.COM {
8807836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_len;	/* FBA len of starting cache block */
8817836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t end_cblk_len;	/* FBA len of ending cache block */
8827836SJohn.Forte@Sun.COM 	sdbc_cblk_fba_t st_cblk_off;	/* FBA offset into starting cblock */
8837836SJohn.Forte@Sun.COM 	nsc_size_t cur_fba_len;
8847836SJohn.Forte@Sun.COM 	_sd_cctl_t  *cc_ent, *cc_ent1;
8857836SJohn.Forte@Sun.COM 	unsigned char *skew_word;
8867836SJohn.Forte@Sun.COM 	int skew_count = 0;
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	ASSERT_HANDLE_LIMITS(handle1, fba_pos1, fba_len);
8897836SJohn.Forte@Sun.COM 	ASSERT_HANDLE_LIMITS(handle2, fba_pos2, fba_len);
8907836SJohn.Forte@Sun.COM 
8917836SJohn.Forte@Sun.COM 	cc_ent = handle1->bh_centry;
8927836SJohn.Forte@Sun.COM 	while (CENTRY_BLK(cc_ent) != FBA_TO_BLK_NUM(fba_pos1))
8937836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
8947836SJohn.Forte@Sun.COM 
8957836SJohn.Forte@Sun.COM 	cc_ent1 = handle2->bh_centry;
8967836SJohn.Forte@Sun.COM 	while (CENTRY_BLK(cc_ent1) != FBA_TO_BLK_NUM(fba_pos2))
8977836SJohn.Forte@Sun.COM 		cc_ent1 = cc_ent1->cc_chain;
8987836SJohn.Forte@Sun.COM 
8997836SJohn.Forte@Sun.COM 	if (BLK_FBA_OFF(fba_pos1) != BLK_FBA_OFF(fba_pos2)) {
900*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Cannot compare unaligned handles");
9017836SJohn.Forte@Sun.COM 		return (0);
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	cur_fba_len = fba_len;
9057836SJohn.Forte@Sun.COM 	st_cblk_off = BLK_FBA_OFF(fba_pos1);
9067836SJohn.Forte@Sun.COM 	st_cblk_len = (BLK_FBAS - st_cblk_off);
9077836SJohn.Forte@Sun.COM 	if ((nsc_size_t)st_cblk_len >= fba_len) {
9087836SJohn.Forte@Sun.COM 		end_cblk_len = 0;
9097836SJohn.Forte@Sun.COM 		st_cblk_len = (sdbc_cblk_fba_t)fba_len;
9107836SJohn.Forte@Sun.COM 	} else
9117836SJohn.Forte@Sun.COM 		end_cblk_len = BLK_FBA_OFF(fba_pos1 + fba_len);
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 	skew_word = cc_ent->cc_data + FBA_SIZE(st_cblk_off);
9147836SJohn.Forte@Sun.COM 	*skew_word = skew | (++skew_count << 24);
9157836SJohn.Forte@Sun.COM 	if (bcmp(cc_ent->cc_data + FBA_SIZE(st_cblk_off),
9167836SJohn.Forte@Sun.COM 	    cc_ent1->cc_data + FBA_SIZE(st_cblk_off),
9177836SJohn.Forte@Sun.COM 	    FBA_SIZE(st_cblk_len)) != 0)
918*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
919*9093SRamana.Srikanth@Sun.COM 		    fba_pos2);
9207836SJohn.Forte@Sun.COM 
9217836SJohn.Forte@Sun.COM 	cur_fba_len -= st_cblk_len;
9227836SJohn.Forte@Sun.COM 	cc_ent = cc_ent->cc_chain;
9237836SJohn.Forte@Sun.COM 	cc_ent1 = cc_ent1->cc_chain;
9247836SJohn.Forte@Sun.COM 
9257836SJohn.Forte@Sun.COM 	while (cur_fba_len > (nsc_size_t)end_cblk_len) {
9267836SJohn.Forte@Sun.COM 		skew_word = cc_ent->cc_data;
9277836SJohn.Forte@Sun.COM 		*skew_word = skew | (++skew_count << 24);
9287836SJohn.Forte@Sun.COM 		if (bcmp(cc_ent->cc_data, cc_ent1->cc_data,
9297836SJohn.Forte@Sun.COM 		    CACHE_BLOCK_SIZE) != 0)
930*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
9317836SJohn.Forte@Sun.COM 			    fba_pos2);
9327836SJohn.Forte@Sun.COM 
9337836SJohn.Forte@Sun.COM 		cc_ent = cc_ent->cc_chain;
9347836SJohn.Forte@Sun.COM 		cc_ent1 = cc_ent1->cc_chain;
9357836SJohn.Forte@Sun.COM 		cur_fba_len -= BLK_FBAS;
9367836SJohn.Forte@Sun.COM 	}
9377836SJohn.Forte@Sun.COM 	if (cur_fba_len) {
9387836SJohn.Forte@Sun.COM 		skew_word = cc_ent->cc_data;
9397836SJohn.Forte@Sun.COM 		*skew_word = skew | (++skew_count << 24);
9407836SJohn.Forte@Sun.COM 		if (bcmp(cc_ent->cc_data, cc_ent1->cc_data,
9417836SJohn.Forte@Sun.COM 		    FBA_SIZE(end_cblk_len)) != 0)
942*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!Data mismatch fba_pos:%" NSC_SZFMT,
9437836SJohn.Forte@Sun.COM 			    fba_pos2);
9447836SJohn.Forte@Sun.COM 	}
9457836SJohn.Forte@Sun.COM 	return (0);
9467836SJohn.Forte@Sun.COM }
9477836SJohn.Forte@Sun.COM 
9487836SJohn.Forte@Sun.COM /*
9497836SJohn.Forte@Sun.COM  * Macro definition for waiting for an IO buffer to be allocated or a read
9507836SJohn.Forte@Sun.COM  * to complete. Macro defined so code doesn't have to be typed each time
9517836SJohn.Forte@Sun.COM  */
9527836SJohn.Forte@Sun.COM #define	WAIT_IO(st, cd, buf, l) \
9537836SJohn.Forte@Sun.COM if ((st != NSC_DONE) && (st != NSC_HIT)) { \
9547836SJohn.Forte@Sun.COM 	if (st != NSC_PENDING) \
955*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!alloc sts: %d", st); \
9567836SJohn.Forte@Sun.COM 	else { \
9577836SJohn.Forte@Sun.COM 		buf = wait_io(cd, &st); \
9587836SJohn.Forte@Sun.COM 		if (st) { \
959*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_WARN, "!ch %d getbuf errpr %d\n", l, st); \
9607836SJohn.Forte@Sun.COM 			if (buf) \
9617836SJohn.Forte@Sun.COM 				(void) _sd_free_buf(buf); \
9627836SJohn.Forte@Sun.COM 			return; \
9637836SJohn.Forte@Sun.COM 		} \
9647836SJohn.Forte@Sun.COM 	} \
9657836SJohn.Forte@Sun.COM }
9667836SJohn.Forte@Sun.COM 
9677836SJohn.Forte@Sun.COM 
9687836SJohn.Forte@Sun.COM #undef  _sd_write
9697836SJohn.Forte@Sun.COM 
9707836SJohn.Forte@Sun.COM static int tiodone, iosent, tioerr;
9717836SJohn.Forte@Sun.COM 
9727836SJohn.Forte@Sun.COM /* ARGSUSED */
9737836SJohn.Forte@Sun.COM 
9747836SJohn.Forte@Sun.COM static void
myend(blind_t arg,nsc_off_t fba_pos,nsc_size_t fba_len,int error)9757836SJohn.Forte@Sun.COM myend(blind_t arg, nsc_off_t fba_pos, nsc_size_t fba_len, int error)
9767836SJohn.Forte@Sun.COM {
9777836SJohn.Forte@Sun.COM 	if (error)
9787836SJohn.Forte@Sun.COM 		tioerr++;
9797836SJohn.Forte@Sun.COM 	else 	tiodone++;
9807836SJohn.Forte@Sun.COM }
9817836SJohn.Forte@Sun.COM 
9827836SJohn.Forte@Sun.COM static int ckd_sskip = 3;
9837836SJohn.Forte@Sun.COM 
9847836SJohn.Forte@Sun.COM /* ARGSUSED3 */
9857836SJohn.Forte@Sun.COM static void
_sd_direct_test(int c,int loop,int seed,int type)9867836SJohn.Forte@Sun.COM _sd_direct_test(int c, int loop, int seed, int type)
9877836SJohn.Forte@Sun.COM {
9887836SJohn.Forte@Sun.COM 	nsc_size_t filesize;
9897836SJohn.Forte@Sun.COM 	int loops;
9907836SJohn.Forte@Sun.COM 
9917836SJohn.Forte@Sun.COM 	int cd;
9927836SJohn.Forte@Sun.COM 	int ckd_hd, recs, rec_size, ckd_doz;
9937836SJohn.Forte@Sun.COM 	int done_size;
9947836SJohn.Forte@Sun.COM 	clock_t st_time;
9957836SJohn.Forte@Sun.COM 	int i;
9967836SJohn.Forte@Sun.COM 
9977836SJohn.Forte@Sun.COM 	int ckd_hd_sz, rec_bsz;
9987836SJohn.Forte@Sun.COM 	int print_stuff;
9997836SJohn.Forte@Sun.COM 	int throttle;
10007836SJohn.Forte@Sun.COM 	struct buf *bp;
10017836SJohn.Forte@Sun.COM 	nsc_off_t curpos;
10027836SJohn.Forte@Sun.COM 
10037836SJohn.Forte@Sun.COM 	caddr_t caddr;
10047836SJohn.Forte@Sun.COM 	iosent = 0;
10057836SJohn.Forte@Sun.COM 
10067836SJohn.Forte@Sun.COM 	print_stuff = 0;
10077836SJohn.Forte@Sun.COM 	seed = gld[c].seed;
10087836SJohn.Forte@Sun.COM 	rec_size = (seed & 0xff);
10097836SJohn.Forte@Sun.COM 	recs = (seed & 0xf00)>>8;
10107836SJohn.Forte@Sun.COM 	ckd_hd = (seed & 0xf000)>>12;
10117836SJohn.Forte@Sun.COM 	ckd_doz = (seed & 0xf0000)>>16;
10127836SJohn.Forte@Sun.COM 	throttle = (seed & 0xff00000)>>20;
10137836SJohn.Forte@Sun.COM 	ckd_hd_sz = ckd_hd * 512;
10147836SJohn.Forte@Sun.COM 	rec_bsz = rec_size * 512;
10157836SJohn.Forte@Sun.COM 
10167836SJohn.Forte@Sun.COM 	done_size = 0;
10177836SJohn.Forte@Sun.COM 	tiodone = 0;
10187836SJohn.Forte@Sun.COM 	curpos = 0;
10197836SJohn.Forte@Sun.COM 	tioerr = 0;
10207836SJohn.Forte@Sun.COM 
10217836SJohn.Forte@Sun.COM 	if (strlen(devarray[c]) == 0) {
1022*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!child %d devarray null\n", c);
10237836SJohn.Forte@Sun.COM 		return;
10247836SJohn.Forte@Sun.COM 	}
10257836SJohn.Forte@Sun.COM 	if ((cd = _sd_open(devarray[c], dev_flag[c])) < 0) {
1026*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!Open error %s child %d\n", devarray[c], c);
10277836SJohn.Forte@Sun.COM 		return;
10287836SJohn.Forte@Sun.COM 	}
10297836SJohn.Forte@Sun.COM 
10307836SJohn.Forte@Sun.COM 	caddr = (caddr_t)nsc_kmem_alloc(20 * 8192, KM_SLEEP, sdbc_local_mem);
10317836SJohn.Forte@Sun.COM 
10327836SJohn.Forte@Sun.COM 	(void) _sd_get_partsize((blind_t)(unsigned long)cd, &filesize);
10337836SJohn.Forte@Sun.COM 	filesize = FBA_SIZE(filesize);
10347836SJohn.Forte@Sun.COM 	loops = ((nsc_size_t)loop > (filesize / (60 * 1024))) ?
10357836SJohn.Forte@Sun.COM 	    (filesize / (60 * 1024)) : loop;
10367836SJohn.Forte@Sun.COM 
10377836SJohn.Forte@Sun.COM 	st_time = nsc_usec();
1038*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_CONT, "!Test 100: %s file %d cd %d loops %x seed\n",
10397836SJohn.Forte@Sun.COM 	    devarray[c], cd, loop, seed);
10407836SJohn.Forte@Sun.COM 	cmn_err(CE_CONT,
1041*9093SRamana.Srikanth@Sun.COM 	    "!Test 100: %d recsize %d recs %d throttle %d hd %d doz\n",
10427836SJohn.Forte@Sun.COM 	    rec_size, recs, throttle, ckd_hd, ckd_doz);
10437836SJohn.Forte@Sun.COM 
10447836SJohn.Forte@Sun.COM 	for (i = 0; i < loops; i++) {
10457836SJohn.Forte@Sun.COM 		curpos = i * 120;
10467836SJohn.Forte@Sun.COM 		if (ckd_doz) {
10477836SJohn.Forte@Sun.COM 			bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
1048*9093SRamana.Srikanth@Sun.COM 			    curpos, 20, B_WRITE);
10497836SJohn.Forte@Sun.COM 			sd_add_mem(bp, caddr, ckd_hd_sz);
10507836SJohn.Forte@Sun.COM 			(void) sd_start_io(bp,
10517836SJohn.Forte@Sun.COM 			    _sd_cache_files[cd].cd_strategy, myend, NULL);
10527836SJohn.Forte@Sun.COM 			iosent++;
10537836SJohn.Forte@Sun.COM 			curpos += ckd_sskip;
10547836SJohn.Forte@Sun.COM 		}
10557836SJohn.Forte@Sun.COM 		if (ckd_doz == 2) {
10567836SJohn.Forte@Sun.COM 			bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
1057*9093SRamana.Srikanth@Sun.COM 			    curpos, 20, B_WRITE);
10587836SJohn.Forte@Sun.COM 			sd_add_mem(bp, caddr, 4096-ckd_sskip*512);
10597836SJohn.Forte@Sun.COM 			(void) sd_start_io(bp,
10607836SJohn.Forte@Sun.COM 			    _sd_cache_files[cd].cd_strategy, myend, NULL);
10617836SJohn.Forte@Sun.COM 			iosent++;
10627836SJohn.Forte@Sun.COM 			curpos += 4096-ckd_sskip*512;
10637836SJohn.Forte@Sun.COM 		}
10647836SJohn.Forte@Sun.COM 		bp = sd_alloc_iob(_sd_cache_files[cd].cd_crdev,
10657836SJohn.Forte@Sun.COM 		    curpos, 20, B_WRITE);
10667836SJohn.Forte@Sun.COM 		sd_add_mem(bp, caddr, recs * rec_bsz);
10677836SJohn.Forte@Sun.COM 		(void) sd_start_io(bp,
10687836SJohn.Forte@Sun.COM 		    _sd_cache_files[cd].cd_strategy, myend, NULL);
10697836SJohn.Forte@Sun.COM 		iosent++;
10707836SJohn.Forte@Sun.COM 
10717836SJohn.Forte@Sun.COM 		done_size += recs * rec_bsz;
10727836SJohn.Forte@Sun.COM 
10737836SJohn.Forte@Sun.COM 		if (tiodone && ((tiodone / 300) > print_stuff)) {
1074*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
10757836SJohn.Forte@Sun.COM 			    tiodone,
10767836SJohn.Forte@Sun.COM 			    ckd_doz ? ((ckd_doz == 2) ?
10777836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz + 4096)) / 3:
10787836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
10797836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz)),
10807836SJohn.Forte@Sun.COM 			    (nsc_usec() - st_time) / 1000);
10817836SJohn.Forte@Sun.COM 			print_stuff++;
10827836SJohn.Forte@Sun.COM 		}
10837836SJohn.Forte@Sun.COM 		while ((iosent - (tiodone + tioerr)) > throttle)
10847836SJohn.Forte@Sun.COM 			;
10857836SJohn.Forte@Sun.COM 	}
10867836SJohn.Forte@Sun.COM 	while ((tiodone + tioerr) < iosent) {
10877836SJohn.Forte@Sun.COM 		if (tiodone && ((tiodone / 300) > print_stuff)) {
1088*9093SRamana.Srikanth@Sun.COM 			cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
10897836SJohn.Forte@Sun.COM 			    tiodone,
10907836SJohn.Forte@Sun.COM 			    ckd_doz ? ((ckd_doz == 2) ?
10917836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz + 4096)) / 3:
10927836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
10937836SJohn.Forte@Sun.COM 			    (tiodone * (recs * rec_bsz)),
10947836SJohn.Forte@Sun.COM 			    (nsc_usec() - st_time) / 1000);
10957836SJohn.Forte@Sun.COM 			print_stuff++;
10967836SJohn.Forte@Sun.COM 		}
10977836SJohn.Forte@Sun.COM 	}
1098*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_CONT, "!Done %d ios %d size in %lu time\n",
10997836SJohn.Forte@Sun.COM 	    tiodone,
11007836SJohn.Forte@Sun.COM 	    ckd_doz ? ((ckd_doz == 2) ?
11017836SJohn.Forte@Sun.COM 	    (tiodone * (recs * rec_bsz + 4096)) / 3:
11027836SJohn.Forte@Sun.COM 	    (tiodone * (recs * rec_bsz + ckd_hd_sz)) / 2) :
11037836SJohn.Forte@Sun.COM 	    (tiodone * (recs * rec_bsz)),
11047836SJohn.Forte@Sun.COM 	    (nsc_usec() - st_time) / 1000);
11057836SJohn.Forte@Sun.COM 
11067836SJohn.Forte@Sun.COM 	print_stuff++;
11077836SJohn.Forte@Sun.COM 	nsc_kmem_free(caddr, 20 * 8192);
11087836SJohn.Forte@Sun.COM }
11097836SJohn.Forte@Sun.COM 
11107836SJohn.Forte@Sun.COM static void
set_parameters(void)11117836SJohn.Forte@Sun.COM set_parameters(void)
11127836SJohn.Forte@Sun.COM {
11137836SJohn.Forte@Sun.COM 	test_stop = 0;
11147836SJohn.Forte@Sun.COM }
11157836SJohn.Forte@Sun.COM 
11167836SJohn.Forte@Sun.COM static nsc_mem_t *dma_test = NULL;
11177836SJohn.Forte@Sun.COM static int *dma_mem = NULL;
11187836SJohn.Forte@Sun.COM 
11197836SJohn.Forte@Sun.COM static int
init_dmatest(void)11207836SJohn.Forte@Sun.COM init_dmatest(void)
11217836SJohn.Forte@Sun.COM {
11227836SJohn.Forte@Sun.COM 	dma_test = nsc_register_mem("dmatest:mem", NSC_MEM_GLOBAL, 0);
11237836SJohn.Forte@Sun.COM 	dma_mem = (int *)nsc_kmem_zalloc(4096, 0, dma_test);
11247836SJohn.Forte@Sun.COM 	if (!dma_mem) {
1125*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_NOTE, "!could not get rm mem\n");
11267836SJohn.Forte@Sun.COM 		return (1);
11277836SJohn.Forte@Sun.COM 	}
1128*9093SRamana.Srikanth@Sun.COM 	cmn_err(CE_NOTE, "!rm = 0x%p\n", (void *)dma_mem);
11297836SJohn.Forte@Sun.COM 	return (0);
11307836SJohn.Forte@Sun.COM }
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM /*ARGSUSED*/
11337836SJohn.Forte@Sun.COM static void
release_dmatest(void)11347836SJohn.Forte@Sun.COM release_dmatest(void)
11357836SJohn.Forte@Sun.COM {
11367836SJohn.Forte@Sun.COM 	nsc_kmem_free(dma_mem, 1);
11377836SJohn.Forte@Sun.COM 	nsc_unregister_mem(dma_test);
11387836SJohn.Forte@Sun.COM 	dma_test = NULL;
11397836SJohn.Forte@Sun.COM 	dma_mem = NULL;
11407836SJohn.Forte@Sun.COM }
11417836SJohn.Forte@Sun.COM /*ARGSUSED*/
11427836SJohn.Forte@Sun.COM static void
test_dma_loop(int net,int seg)11437836SJohn.Forte@Sun.COM test_dma_loop(int net, int seg)
11447836SJohn.Forte@Sun.COM {
11457836SJohn.Forte@Sun.COM 	delay(3*HZ);
11467836SJohn.Forte@Sun.COM 
11477836SJohn.Forte@Sun.COM 	if (!dma_mem && init_dmatest()) {
1148*9093SRamana.Srikanth@Sun.COM 		cmn_err(CE_WARN, "!test_dma_loop: init failed");
11497836SJohn.Forte@Sun.COM 		return;
11507836SJohn.Forte@Sun.COM 	}
11517836SJohn.Forte@Sun.COM 
11527836SJohn.Forte@Sun.COM 	/*
11537836SJohn.Forte@Sun.COM 	 * The body of test loop is removed since we don't use any more
11547836SJohn.Forte@Sun.COM 	 */
11557836SJohn.Forte@Sun.COM 
11567836SJohn.Forte@Sun.COM 	release_dmatest();
11577836SJohn.Forte@Sun.COM }
1158