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