STB Suite

January 2010

External Tests from DMM – SATA SelfTestSTB Suite v8.1

The ability to call any external program as a test step from within a DMM test sequence allows any new type of test to be added to the DMM test pallet. By using the Developers Toolbox (DTB) api you can send any command to any type of device.

This example will illustrate how to run a SATA SMART Self Test as a DMM test step, logging the results to the DMM device log file.

A C++ program to execute the SATA Self Test

Using Microsoft Visual Studio C++ and the STB Suite Developers Toolbox api we can send any command we need to any type of device. Since DMM is communicating with SATA devices via a SAS controller which implements SAT (SCSI->ATA Translation) such as the LSI 3800 or 3801 we must write our program to issue the SATA command imbedded into a SCSI command, according to the SAT standard.

For this test we will run the default short SATA Self Test.

To illustrate how easy it is to add a new test like this to DMM you will note that the sample source code is well under 200 lines.

Our example project retrieves the address of the drive from the command line arguments passed by DMM. In addition DMM allows you to pass additional user defined command line arguments to your program. For example, you could modify this project to allow you to specify any of the different SATA Self Tests.

DMM can also receive information passed back to it by the called external program. In the case of this example we will respond back to DMM with a text message saying whether the self test executed correctly or not. DMM runs the external programs as separate threads on each device under test, and so each separate device will get back only its own response string.

 

The code to issue the self test command using the DTB User Defined SCSI command simply defines the proper command and issues it with one DTB function call as follows:

External SATA Tests in DMM

Summary

This quick example illustrates how simply and quickly completely new tests can be added to the DMM test pallet. From simple commands like this example uses, through highly complex tests, any new function is easily added to DMM via the DMM External Test test step.

To request the complete Visual Studio project files for this example please contact Jeremy Wolfe at sales@scsitoolbox.com.

 

 

 

SATA Drive Confidence Test #2 – Long
STB Suite v8.1Introduction

Two of the oldest disk tests in the STB Suite are the Confidence Test 1 and Confidence Test 2. These tests were first included in the original DOS version of the SCSI Toolbox in the early 1990s.

The philosophy of these tests was to stress and test as many drive functions as possible in a relatively short time.

The tradition of these tests is continued into the SATA world with the new pair of SATA confidence tests.

This article will describe the second test, which is the more thorough of the two.

These new tests issue native SATA task register commands and so it is necessary to have your disk drive connected to your test system via one of your motherboard SATA ports.

What the test tests

SATA Confidence #1 is accessed via the STB Suite Original Mode top menu ATA/SATA->Tests->Drive Confidence 1 (Quick Test) menu choice.

The drives available for test (drives connected to your motherboard SATA ports) are shown on the right side of the display. Click on the drive you wish to test. The test steps which will be run are listed under the Test Description section.

This SATA Long Test runs the following test steps:

  • Record drive SMART data
  • Record drive SMART Self Test logs
  • Execute a SMART Self Test
    • either a SHORT, EXTENDED, CONVEYANCE, OR SELECTIVE test
      • the run times for the various types of self tests are displayed below the test type selection area.Some drives will not show a time for the CONVEYANCE test type. BTW- the CONVEYANCE test is used to detect problems induced when the drive has been shipped.
  • Read 100 MB of data from the beginning, middle, and end of the drive, displaying transfer rate
  • Write 100 MB of data at the beginning, middle, and end of the drive – if the Destructive Testing option is checked.
  • Displays transfer rates for each section.
  • Execute random seeks/reads for 5 minutes
  • Record drive SMART data again
  • Record drive SMART Self Test logs again

 

 

As the test progresses the various steps will be shown in blue as the step executes, and once the step is complete it will be displayed either in green if the step passed or in red if the step failed – here the test has executed the first three steps with no errors –

Also note that the details of each test step are logged to the Test Status/Results window. All SMART information, SMART test logs, IDENTIFY information, and transfer rate performance metrics are recorded.

Once the test is finished you may click the Save Results to File button to save the test log. The default file name for the log is shown – it is made up of the drive type and serial number. You may change the log file name if you have your own log naming method.

 

Test Results Output

Test results may be viewed by scrolling the Test Status/Results window or by saving the log to a file. The saved log file will be a text file – here is an example:

Summary

This SATA Long Test runs the following test steps:

  • Record drive SMART data
  • Record drive SMART Self Test logs
  • Execute a SMART Self Test – either a SHORT, EXTENDED, CONVEYANCE, OR SELECTIVE test-the run times for the various types of self tests are displayed below the test type selection area.Some drives will not show a time for the CONVEYANCE test type. BTW- the CONVEYANCE test is used to detect problems induced when the drive has been shipped.
  • Read 100 MB of data from the beginning, middle, and end of the drive, displaying transfer rate
  • Write 100 MB of data at the beginning, middle, and end of the drive – if the Destructive Testing option is checked. – Displays transfer rates for each section.
  • Execute random seeks/reads for 5 minutes
  • Record drive SMART data again
  • Record drive SMART Self Test logs again

 

This test will take longer to complete than the quick test (Confidence Test #1), but it offers the advantage of executing any type of SMART Self Test and also offers the option of write testing and write performance measurement.

 

 

 

Introduction to the Command Probability Sequencer
STB Suite 8.1 iconThe Command Probability Sequencer (CPS) is a new API in VCPSSL v8.2.0 that allows you to define a set of commands that will be issued; each command has a specified probability it will be chosen for execution. This new API is quite complex and has many features – we will introduce the features by way of examples.

As a first example, suppose you wanted to issue a lot of writes and reads, but every now and then issue a different command (like Log Sense command for example). And suppose you have a further requirement that this Log Sense command be issue about every 1000th I/O. The Command Probability Sequencer is perfect for implementing the above test scenario. Although the coding example below at first looks daunting, but for now focus on the following items: we are setting up three user-defined commands “Write”, “Read”, and “Log Sense” and we need to specify such information as whether data is going to/from the drive (the “nDataDir” field), and how much data needs to be transfer (the “nTransferLen” field). Here’s the code for our first example – focus on the lines of code in RED which have the “nDataDir” and “nTransferLength” parameters, and the actual definition of the commands.

 

const int c_nLenOfArray = 3;

DMM_UserDefinedCDB arrOfCDB[c_nLenOfArray];

double arrOfProb[c_nLenOfArray];

int nIndex;

const long c_lNumberOfIOToIssue = 10000;

//Set up the “Write” command (Write is opcode 0x2A)

BYTE cCDB0[] = {0x2A,0,0,0,0,0,0,0,1,0};

nIndex = 0;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB0,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 0;

arrOfCDB[nIndex].nTransferLength = 512;

//Set up the “Read” command (Read opcode is 0x28)

BYTE cCDB1[] = {0x28,0,0,0,0,0,0,0,1,0};

nIndex = 1;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB1,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 1;

arrOfCDB[nIndex].nTransferLength = 512;

//Set up the “Log Sense” command (Log Sense opcode is 0x4D)

BYTE cCDB2[] = {0x4D,0,0×40,0,0,0,0,0,0,0×80,0};

nIndex = 2;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB2,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 1;

arrOfCDB[nIndex].nTransferLength = 128;

//Now define the probabilities for each of the three commands

//“Write”, “Read”, “Log Sense”

arrOfProb[0] = 0.4995; //this is the probability for the “Write” command

arrOfProb[1] = 0.4995; //this is the probability for the “Read” command

arrOfProb[2] = 0.001; //.001 probability means the Log Sense command will be issued

//with probability .001 (i.e. every 1000th I/O)

VCSCSIAddDiskComProbSeqTest(arrOfCDB,

arrOfProb,

c_nLenOfArray,

c_lNumberOfIOToIssue);

In the example above our set of commands to issue is 3 (hence we set c_nLenOfArry to 3) and the number of commands to issue is 10000 (hence we set c_lNumberOfIOToIssue to 10000). Notice also in the call to API VCSCSIAddDiskComProbSeqTest we pass in two arrays: the first is the sequence of commands, and the second is the sequence containing the probabilities for these commands.

NOTE: The sum of your probabilities must be exactly 1.0 (or 100%). Notice in our example the sum of the probabilities .4995, .4995, and .001 is exactly 1.0

Here is a BAM (Bus Analyzer Module) output from the above test:

As you can see in the trace, there are Write, Log Sense, and Read commands. In the lower portion of the trace, on the I/O Statistics page, it shows the number and type of commands that went out. There were 5019 Read commands, 4966 Write commands, and 15 Log Sense commands (note that 5019 + 4966 + 15 = 10000, which is the number of commands we specified to CPS to issue). From this particular run, we see that the Read commands formed 5019/10000 = 50.19% of the commands, the Write commands formed 4966/10000 = 49.66% of the commands, and the Log Sense commands formed 15/10000 = 0.15%. These percentages are almost exactly the probabilities we specified to CPS.

 

SECOND EXAMPLE: Writing Every Even LBA With An Incrementing Pattern and Every Odd LBA with a Decrementing Pattern

In this example we will cover two more features of the CPS – namely how to set the data pattern, and how to adjust your write and read (and other commands) automatically. To see why you would want to adjust the write command, suppose for the moment you did not adjust the command. Then every single time we issued the command we would be writing to the exact same location on the drive (in example 1, we would be writing to LBA 0 every single time). To allow adjusting the location the command writes to, we have introduced the “nGap” parameter. The nGap parameter tells CPS how much to adjust the location of the write command. For example, if nGap is 7 then successive writes would go to LBAs 0, 7, 14, 21, and so forth.

In order to write every even LBA (i.e. the LBAs 0, 2, 4, 6, 8, 10, ….) we will need nGap to be exactly 2.

So here’s how to see up the above type of test – focus on the lines of code in RED which have the “eTestPattern” and “nGap” parameters.

const int c_nLenOfArray = 2;

DMM_UserDefinedCDB arrOfCDB[c_nLenOfArray];

double arrOfProb[c_nLenOfArray];

int nIndex;

const long c_lNumberOfIOToIssue = 10000;

//Set up the “Write” command that writes to even LBA, with Incrementing pattern

BYTE cCDB0[] = {0x2A,0,0,0,0,0,0,0,1,0};

nIndex = 0;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB0,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 0;

arrOfCDB[nIndex].nTransferLength = 512;

arrOfCDB[nIndex].eTestPattern = eIncrementing;

arrOfCDB[nIndex].nGap = 2;

//Set up the “Write” command that writes to odd LBA, with Decrementing pattern

BYTE cCDB1[] = {0x2A,0,0,0,0,1,0,0,1,0};

nIndex = 1;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB1,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 0;

arrOfCDB[nIndex].nTransferLength = 512;

arrOfCDB[nIndex].eTestPattern = eDecrementing;

arrOfCDB[nIndex].nGap = 2;

//Now define the probabilities for these two commands. There’s no reason you have

//to make the probabilities the same.

arrOfProb[0] = 0.71; //71% of the time we’ll be writing to the even LBA

arrOfProb[1] = 0.29; //29% of the time we’ll be writing to the odd LBA

VCSCSIAddDiskComProbSeqTest(arrOfCDB,

arrOfProb,

c_nLenOfArray,

c_lNumberOfIOToIssue);

 

Here is a BAM (Bus Analyzer Module) output from the above test:

Notice in the BAM trace, the first Write command writes a decrementing pattern (to LBA 1), while the next three Write commands write an incrementing pattern (to LBA 0, 2, 4). Notice the “spacing” between the Write commands with incrementing pattern – they are exactly two blocks apart, which is exactly the nGap value we specified to CPS.

 

THIRD EXAMPLE: SENDING SPECIALIZE DATA TO THE DRIVE

In this third example we show you how to send unique data to a drive in a “Mode Select” command. We will be setting the AWRE (“Automatic Write Reallocation Enabled” bit to 0 on the “Error Recovery” mode page). This Mode Select will be done only with probability one-tenth of one percent (i.e. probability .001).

const int c_nLenOfArray = 3;

DMM_UserDefinedCDB arrOfCDB[c_nLenOfArray];

double arrOfProb[c_nLenOfArray];

int nIndex;

const long c_lNumberOfIOToIssue = 10000;

//Do a Mode-Select (Mode-Select has opcode 0x15)

BYTE cCDB0[] = {0x15,0x11,0,0,0×18,0};

BYTE cModeSelectBuffer[24] = {0,0,0,0×08,0,0,0,0,0,0,2,0,1,0x0a,4,1,0,0,0,0,1,0,0,0};

nIndex = 0;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB0,6);

arrOfCDB[nIndex].nCDBLength = 6;

arrOfCDB[nIndex].nDataDir = 0;

arrOfCDB[nIndex].nTransferLength = 24;

arrOfCDB[nIndex].pPayloadDataToDrive = &cModeSelectBuffer[0];

//Set up the “Write” command (Write is opcode 0x2A)

BYTE cCDB1[] = {0x2A,0,0,0,0,0,0,0,1,0};

nIndex = 1;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB1,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 0;

arrOfCDB[nIndex].nTransferLength = 512;

//Set up the “Read” command (Read opcode is 0x28)

BYTE cCDB2[] = {0x28,0,0,0,0,0,0,0,1,0};

nIndex = 2;

memcpy(arrOfCDB[nIndex].cCDBBytes,cCDB2,10);

arrOfCDB[nIndex].nCDBLength = 10;

arrOfCDB[nIndex].nDataDir = 1;

arrOfCDB[nIndex].nTransferLength = 512;

//Now define the probabilities for these two commands. There’s no reason you have

//to make the probabilities the same.

arrOfProb[0] = 0.001; // .1% of the time we issue mode-select

arrOfProb[1] = 0.4995;

arrOfProb[2] = 0.4995;

VCSCSIAddDiskComProbSeqTest(arrOfCDB,

arrOfProb,

c_nLenOfArray,

c_lNumberOfIOToIssue);

 

Here is a BAM (Bus Analyzer Module) output from the above test:

 

DEFINITIONS OF THE PARAMETERS FOR EACH COMMAND:

Here is the data structure that you must fill out for each command you want to set up for CPS:

struct _DMM_UserDefinedCDB

{

BOOL bValid;

eUSER_DEFINED_TYPES eUserDefinedType;

char cCDBBytes[16];

int nCDBLength;

int nDataDir;

int nTimeout;

int nTransferLength;

BYTE * pPayloadDataToDrive;

int nAmtDataToLogfile;

char cDataOutFile[MAX_PATH];

ePATTERN_TYPE eTestPattern;

BOOL bCompare;

int nGap;

int nSeed;

}

bValid: Set it to TRUE
eUserDefinedType: Set it to eScsiCDB
cCDBBytes: copy the particular command to this field (must be 16 bytes or less)
nCDBLength: set this to the length of your command
nDataDir: set this to 0 if data is going TO the drive, and set it to 1 if data is coming BACK from the drive. NOTE: If no data is being transferred, set it to 0. 0 is the default value
nTimeout: set this to the desired timeout for the command (default value is 30)
nTransferLength: set this to how much data is to be transferred. If no data is being transferred then set this field to 0
pPayloadDataToDrive: set this pointer to the starting address of the buffer containing the data to be shipped to the drive. If there is no data to be shipped to the drive then set this field to NULL (which is the default value).
cDataOutFile: set byte 0 to ‘\0’ – this is the default
eTestPattern: set this field to the desired pattern. For a list of available patterns see VCPSSLImports.h and enum ePATTERN_TYPE.
bCompare: Set this field to TRUE if the command is receiving data from the drive (for example a “Read” command). Otherwise set it to FALSE (which is the default). The data coming back from the drive will be compared to whatever is in the eTestPattern field
nGap: for Write and Read commands, set this field to the number of blocks you want between each successive commands

 

RETURN CODES AND POSSIBLE PROBLEMS WITH USING VCSCSIAddDiskComProbSeq API:

This API returns TRUE to mean adding of the test to your sequence was done;

It returns FALSE if any problem occurred.

Reasons for getting a return code of FALSE from API VCSCSIAddDiskComProbSeq:

  1. The number of commands in your sequence is too long. Resolution: Make sure there are at most 1000 commands in your sequence
  2. The sum of the probabilities for all your commands does not equal 1.0. Resolution: Make sure that the probabilities do in fact add up to 1.0 – it is very easy to “misplace” a decimal point or incorrectly input numbers. Also, input the numbers as, for example, .25 (NOT as 25).

View this article for here.

 

 

 

 

Customized training with an STB technician
STB TrainingDo you have questions about how to best use the STB Suite in your business? STB is happy to work with you in an interactive “live” environment to help you get the most out of your Toolbox. The cost? If you are a current Performa customer it is free! The commitment? Training sessions run between 30 and 60 minutes.

Here is a list of some recent customer training sessions that STB has conducted – live, interactive web sessions presented by STB programmers:

  1. Three stages of disk drive screening
  2. How to troubleshoot tape drive problems
  3. RAID issues in disk drive testing
  4. Multi-drive SATA firmware downloading with the STB Suite

Contact Jeremy Wolfe at (720) 249-2641 today to schedule your own custom training session!