/*
* RANDOM
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <mem.h>
#include "global.h"
#include "script.h"
#include "aspi_rw.h"
#include "kbd.h"
#include "dmem.h"
#include "buf.h"
#include "print.h"
#define BLK_SIZE 512
#define MAX_BLKS 120
static FLAG auto_init = FALSE;
/***************************************************************************
*
* rand_aspi(...)
*
***************************************************************************/
FLAG rand_aspi(
char *cmd,
struct SCRIPT_OBJ *script,
unsigned long num_req,
unsigned int scsi_id_first,
unsigned int scsi_id_last,
unsigned int num_blks_min,
unsigned int num_blks_max,
unsigned long blk_num_first,
unsigned long blk_num_last,
U16 tag,
unsigned int pattern)
{
char *aspi_cmd;
unsigned int scsi_id;
unsigned long blk_num;
int rand_num;
int i = 0;
FILE *file_log;
FLAG read_only = FALSE;
time_t t;
FLAG ret_val = TRUE;
unsigned int num_blks;
long ltemp;
time_t time_st,time_end;
static long time_total = 0;
static U32 num_blks_total = 0;
//
//
//
printf("ASPI Random Request Generator\n");
printf("\tNumber of requests to be generated: %ld\n",num_req);
printf("\tSCSI ID range: %u to %u\n",scsi_id_first,scsi_id_last);
printf("\tBlock Number range: %lu to %lu\n",blk_num_first,blk_num_last);
printf("\tNumber of Blocks Range per Request: %u to %u\n",num_blks_min,
num_blks_max);
if ((blk_num_first - blk_num_last + 1) < num_blks_max)
{
error("Max number of Blocks can cause overflow of last Block");
return (FALSE);
}
if (!script->loop
&&
(auto_init
||
kbd_get_yn("Initialize blocks for speced range of SCSI IDs and Block Numbers")
)
)
{
aspi_cmd = "W"; /* Spec write */
printf("%sInitializing...\n",auto_init?"Automatically ":"");
ltemp = ((dmem_size()/BLK_SIZE) - 5) / (script->aspi_allow_reqs + 1);
if (ltemp > MAX_BLKS)
ltemp = MAX_BLKS;
if (ltemp < 0)
ltemp = 1;
ltemp = 10;/* */
for (scsi_id = scsi_id_first; scsi_id <= scsi_id_last; scsi_id++)
{
num_blks = ltemp;
if ((blk_num_last - blk_num_first + 1) < num_blks)
num_blks = blk_num_last - blk_num_first + 1;
for (blk_num = blk_num_first; ; blk_num += num_blks)
{
if ((blk_num + num_blks - 1) > blk_num_last)
num_blks = (blk_num + num_blks) - blk_num_last - 1;
if (!aspi_rw(aspi_cmd,scsi_id,blk_num,num_blks,tag,pattern))
return (FALSE);
if (i > 100) // Modulo 100
{
printf( "SCSI ID: %d, up to block %ld%c",
scsi_id,
(long)(blk_num + num_blks - 1),0x0D);
i = 0;
}
else
i += num_blks;
if ((blk_num + num_blks) >= blk_num_last)
break;
}
printf("\nSCSI ID: %d initialized.\n",scsi_id);
}
aspi_flush();
aspi_stats('c'); /* Clear stats */
diag_msg("Done initializing...\n");
}
diag_msg("Generating requests...\n");
//
// Log file
//
if (diag_here(DIAG_LOG_FILE))
{
file_log = fopen("AE.LOG","w");
t = time(NULL);
fprintf( file_log,
"*VER_COMPAT %d\n*ECHO File produced by Random Request Log, %s\n"
"*REQ_OUTSTANDING %d\n",
MIN_VC_NUM,ctime(&t),script->aspi_allow_reqs);
}
//
// Request loop
//
if (cmd[1] && (toupper(cmd[1]) == 'R')) // Read-only, i.e. all cache
{
read_only = TRUE; // Spec read-only
aspi_cmd = "R"; // Spec read
}
//
// Time statistics
//
time_st = time(NULL);
for (i = 0; i < num_req; i++)
{
if (!read_only)
{
rand_num = random(2);
if (!rand_num) /* Write? */
if (toupper(cmd[2]) == 'V') // Write verify?
aspi_cmd = "WV"; // Spec write verify
else // Normal write?
aspi_cmd = "W"; // Spec normal write
else /* */
aspi_cmd = "R"; /* Spec read */
}
//
// Don;t allow number of blocks to cause an overflow by going
// beyond the last block specified.
//
scsi_id = random(scsi_id_last - scsi_id_first + 1) + scsi_id_first;
num_blks = random(num_blks_max - num_blks_min + 1) + num_blks_min;
blk_num = random(blk_num_last - blk_num_first + 1) + blk_num_first;
if ((blk_num + num_blks - 1) > blk_num_last) // Overflow?
num_blks = blk_num_last - blk_num + 1; // Adjust
if (diag_here(DIAG_VERBOSE))
printf("Random ASPI command: %s.\n",aspi_cmd);
if (diag_here(DIAG_LOG_FILE))
fprintf(file_log,"*ASPI %s %u %lu %u %u %u\n",
aspi_cmd,
scsi_id,
blk_num,
num_blks,
tag,
pattern);
num_blks_total += num_blks;
// Test to mask bits 4 and 5
if (cmd[1] && (toupper(cmd[1]) == 'M')) // Mask?
do
{
if (cmd[2] && (cmd[2] == '4')) // Bits 4-7?
{
blk_num &= 0xFFFFFF0F;
break;
}
if (cmd[2] && (cmd[2] == '0')) // Bits 0-3?
{
blk_num &= 0xFFFFFFF0;
break;
}
if (cmd[2] && (cmd[2] == 'B')) // Both bits 4 & 5 and bits 8 & 9?
{
blk_num &= 0xFFFFFF00;
break;
}
if (cmd[2] && (cmd[2] == 'F')) // Detect 0xFF?
{
if ((blk_num & 0x000000FF) == 0x000000FF)
blk_num &= 0xFFFFFF00;
break;
}
}
while (FALSE);
if (!aspi_rw(aspi_cmd,scsi_id,blk_num,num_blks,tag,pattern))
break;
if (kbd_double_esc())
{
if (kbd_get_yn("ABORT Random Request Generator"))
{
diag_msg("User abort during generation of random requests.\n");
ret_val = FALSE;
break;
}
}
if (!(i & 0x0000000F)) // Modulo 16
printf("Up to request %d%c",i,0x0D);
}
printf("\n");
//
// Time statistics
//
time_end = time(NULL);
time_total += difftime(time_end,time_st);
printf("Averages:\n");
printf("\tTotal Kbytes: %ld\n\tTotal secs: %ld\n",
(num_blks_total/2),time_total);
printf("\tTotal: %ld Kbytes/sec\n",
(num_blks_total/2)/time_total);
if (diag_here(DIAG_LOG_FILE))
{
fprintf(file_log,"*ECHO End of Script file\n");
fprintf(file_log,"*ABORT\n");
fclose(file_log);
}
return (ret_val);
}
/***************************************************************************
*
* rand_auto_init(...)
*
***************************************************************************/
void rand_auto_init(void)
{
auto_init = TRUE;
}