scsiTest.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* scsiTest.c - Program to test SCSI library */
  2. /* Copyright 1994 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01c,25sep96,dds  added documentation and corrected for wrs coding standards.
  8. 01b,17jun94,jds  added check in testDirectCmdsAll for 10 byte commands not
  9.                  supported by SCSI device.
  10. 01a,29apr94,jds  written
  11. */
  12. /* 
  13. DESCRIPTION
  14. These set of routines are written to test the functionality of the SCSI
  15. library. This object module must be loaded after "scsiTestLib.o" has
  16. been loaded.
  17. */
  18. #define INCLUDE_SCSI2
  19. #include "vxWorks.h"
  20. #include "tickLib.h"
  21. #include "taskLib.h"
  22. #include "ioLib.h"
  23. #include "memLib.h"
  24. #include "usrLib.h"
  25. #include "fppLib.h"
  26. #include "scsiLib.h"
  27. #include "scsi2Lib.h"
  28. #include "stdio.h"
  29. /* defines */
  30. #define FACTOR (0x800 * 512)
  31. #define TOTAL 0x1000000
  32. #define BLOCK (0x400 * 512)
  33. #define LINES (TOTAL / FACTOR)
  34. #define THIS_TASK 0
  35. /* Note: change size according to the tape drive under test */
  36. #define FIXED_BLK_SIZE 0x400 /* default fixed block size for Exabyte drive */
  37. IMPORT errno;
  38. IMPORT STATUS errnoGet ();
  39. IMPORT STATUS scsiTargetOptionsGet ();
  40. IMPORT STATUS scsiTargetOptionsSet ();
  41. IMPORT STATUS scsiTestTestUnitRdy ();
  42. IMPORT VOID logMsg ();
  43. IMPORT STATUS scsiTestReqSense ();
  44. IMPORT STATUS scsiTestTapeModeSense ();
  45. IMPORT STATUS scsiTestTapeModeSelect ();
  46. IMPORT STATUS scsiTestReadBlockLimits ();
  47. IMPORT STATUS scsiTestLoad ();
  48. IMPORT STATUS scsiTestUnload ();
  49. IMPORT STATUS scsiTestReserveUnit ();
  50. IMPORT STATUS scsiTestRewind ();
  51. IMPORT STATUS scsiTestErase ();
  52. IMPORT STATUS scsiTestReleaseUnit ();
  53. IMPORT STATUS scsiTestWrtFileMarks ();
  54. IMPORT STATUS scsiTestSpace ();
  55. IMPORT STATUS scsiTestWrtTapeVar ();
  56. IMPORT STATUS scsiTestWrtTapeFixed ();
  57. IMPORT STATUS scsiTestRdTapeVar ();
  58. IMPORT STATUS scsiTestRdTapeFixed ();
  59. IMPORT STATUS scsiTestInquiry ();
  60. IMPORT STATUS scsiTestModeSense ();
  61. IMPORT STATUS scsiTestModeSelect ();
  62. IMPORT STATUS scsiTestReserve ();
  63. IMPORT STATUS scsiTestRelease ();
  64. IMPORT STATUS scsiTestReadCapacity ();
  65. IMPORT STATUS scsiTestStartStopUnit ();
  66. IMPORT STATUS scsiTestFormatUnit ();
  67. IMPORT STATUS scsiTestWrtSecs ();
  68. IMPORT STATUS scsiTestRdSecs ();
  69. IMPORT STATUS scsiIoctl ();
  70. /* stdlib functions */
  71. IMPORT int strcpy ();
  72. IMPORT int strlen ();
  73. IMPORT int strcmp ();
  74. IMPORT int bzero ();
  75. IMPORT int strncmp ();
  76. /* global variables */
  77. char scsiTestBuffer[500];
  78. int  scsiMaxBlockLimit;
  79. UINT16 scsiMinBlockLimit;
  80. union mixed
  81. {
  82.     char * string;
  83.     int testNo;
  84. };
  85. /******************************************************************************
  86. *
  87. * optionSet - set maxOffset and minPeriod for the scsi target
  88. *
  89. * This function call scsiTargetOptionsSet to set option for scsi target
  90. * Variables need to be changed:
  91. * busID
  92. * which
  93. * option.maxOffset/option.minPeriod
  94. * RETURNS: OK if passes, or ERROR if an error is encountered.
  95. */
  96. int optionSet()
  97.     {
  98.     SCSI_OPTIONS option;
  99.     
  100.     int which;
  101.     int busID = 0;
  102.     option.maxOffset = 0;
  103.     option.minPeriod = 25;
  104.     
  105.     which = SCSI_SET_OPT_XFER_PARAMS; 
  106.     
  107.     if (scsiTargetOptionsSet(pSysScsiCtrl, busID, &option, which) == ERROR) 
  108. {
  109. SCSI_DEBUG_MSG("userScsiConfig: could not set optionsn",0,0,0,0,0,0);
  110. return(ERROR);
  111. }
  112.     return (OK);
  113.     }
  114. /******************************************************************************
  115. *
  116. * testCommonCmds - test scsi commands common to sequential & direct devices
  117. *
  118. *  test all mandatory and commonn scsi commands for sequential devices and
  119. *  direct access devices. These commands are
  120. * 1. TEST UNIT READY
  121. * 2. REQUEST SENSE
  122. * 3. INQUIRY
  123. * RETURNS: OK if passes, or ERROR if an error is encountered.
  124. */
  125. STATUS testCommonCmds
  126.     (
  127.     SCSI_PHYS_DEV *pScsiPhysDev
  128.     )
  129.     {
  130.     /* retry if unit attention */
  131.     if (scsiTestTestUnitRdy (pScsiPhysDev) == ERROR)
  132.         {
  133.         if (errnoGet() == S_scsiLib_UNIT_ATTENTION)
  134.             {
  135.             if (scsiTestTestUnitRdy (pScsiPhysDev) == ERROR)
  136.                 return (ERROR);
  137.             else
  138.                 printf ("Pass TEST UNIT READYn");
  139.             }
  140.         else
  141.             return (ERROR);
  142.         }
  143.     
  144.     /* if TUR OK then do a Request Sense */
  145.     if (scsiTestReqSense (pScsiPhysDev, scsiTestBuffer,
  146.   REQ_SENSE_ADD_LENGTH_BYTE + 1) == ERROR)
  147.         return (ERROR);
  148.     
  149.     /* if REQUEST SENSE OK then do an INQUIRY */
  150.     if (scsiTestInquiry (pScsiPhysDev, scsiTestBuffer, 36) == ERROR)
  151.         return (ERROR);
  152.     
  153.     return (OK);
  154.     }
  155. /******************************************************************************
  156. *
  157. * testDirectCmdsAll - test all direct access device (disk) commands
  158. *
  159. * test all the direct access commands. FORMAT command is optionally tested
  160. * by specifying the boolean parameter doFormat as TRUE
  161. * test the following commands:
  162. * 1. MODE SENSE 6
  163. * 3. MODE SELECT 6
  164. *  5. RESERVE
  165. * 6. RELEASE
  166. * 7. READ CAPACITY
  167. * 8. READ 6
  168. * 10. WRITE 6
  169. * 12. START STOP UNIT
  170. * 13. FORMAT (optional)
  171. *
  172. * RETURNS: OK if passes, or ERROR if an error is encountered.
  173. */
  174. STATUS testDirectCmdsAll
  175.     (
  176.     SCSI_PHYS_DEV *pScsiPhysDev,
  177.     SCSI_BLK_DEV *pBlkDev,
  178.     BOOL     doFormat
  179.     )
  180.     {
  181.     int  lastLBA;
  182.     int  blkLength;
  183.     char *buffer;
  184.     int  i;
  185.     int  blockNumber;
  186.     int  ctrlBusId;
  187.     
  188.     
  189.     buffer = (char *) malloc (512 * 257);
  190.     
  191.     /* 6 Byte Mode Sense */
  192.     
  193.     if (scsiTestModeSense (pScsiPhysDev, 0x00, 0x00, buffer, 0x0c) == ERROR)
  194.         return (ERROR);
  195.     
  196.     buffer[0] = 0x00;
  197.     buffer[1] = 0x00;
  198.     buffer[2] = buffer[2] & 0x7f;
  199.     
  200.     /* 6 Byte Mode Select */
  201.     
  202.     if (scsiTestModeSelect (pScsiPhysDev, 1, 0, buffer, 0x0c) == ERROR)
  203.         return (ERROR);
  204.     
  205.     if (scsiTestReserve (pScsiPhysDev) == ERROR)
  206.         return (ERROR);
  207.     
  208.     if (scsiTestRelease (pScsiPhysDev) == ERROR)
  209.         return (ERROR);
  210.     
  211.     if (scsiTestReadCapacity (pScsiPhysDev, &lastLBA, &blkLength) == ERROR)
  212.         return (ERROR);
  213.     
  214.     if (scsiTestStartStopUnit (pScsiPhysDev, FALSE) == ERROR)
  215.         return (ERROR);
  216.     
  217.     if (scsiTestStartStopUnit (pScsiPhysDev, TRUE) == ERROR)
  218.         return (ERROR);
  219.     
  220.     if (doFormat)
  221.         {
  222.         if (scsiTestFormatUnit (pScsiPhysDev, 0, 0, 0, 0, (char *) NULL, 0)
  223.     == ERROR)
  224.             return (ERROR);
  225.         }
  226.         
  227.     ctrlBusId = pScsiPhysDev->pScsiCtrl->scsiCtrlBusId;
  228.     
  229.     blockNumber = 1000 * ctrlBusId;
  230.     
  231.     /* initialize buffer with pattern */
  232.     
  233.     for (i=0; i < 512; i++)
  234.         buffer[i] = 'a';
  235.     
  236.     /* 6 BYTE WRITE AND READ */
  237.     
  238.     /* write the pattern to 1 sector */
  239.     if (scsiTestWrtSecs (pBlkDev, blockNumber, 1, buffer) == ERROR)
  240.         return (ERROR);
  241.     
  242.     /* read pattern from sector written to */
  243.     if (scsiTestRdSecs (pBlkDev, blockNumber, 1, buffer) == ERROR)
  244.         return (ERROR);
  245.     
  246.     free (buffer);
  247.     
  248.     return (OK);
  249.     }
  250. /******************************************************************************
  251. *
  252. * testDirectRW - test direct access device (disk) read and write commands
  253. *
  254. * test the following scenarios:
  255. * 1. write, read and check data pattern for 6Byte commands
  256. * 2. write, read and check data pattern for 10Byte commands
  257. * In doing so, cache coherency will automatically get tested
  258. *
  259. * RETURNS: OK if passes, or ERROR if an error is encountered.
  260. */
  261. STATUS testDirectRW
  262.     (
  263.     SCSI_PHYS_DEV *pScsiPhysDev, /* physical device structure pointer    */
  264.     SCSI_BLK_DEV *pBlkDev,       /* ptr to block device                  */
  265.     int  numLoops,  /* number of times to do RW test        */
  266.     BOOL noDataCompare   /* default (0) means do data comparison */
  267.     )
  268.     {
  269.     char *buffer;
  270.     int  i;
  271.     int blockNumber;
  272.     int loops;
  273.     int ctrlBusId;
  274.     
  275.     if (numLoops == 0)
  276. numLoops = 1;
  277.     
  278.     buffer = (char *) malloc (512 * 1);
  279.     
  280.     ctrlBusId = pScsiPhysDev->pScsiCtrl->scsiCtrlBusId;
  281.     
  282.     blockNumber = 1000 * ctrlBusId;
  283.     /* if numLoops is negative then loop forever */
  284.     for (loops = 0; loops != numLoops; loops++)
  285. {
  286.         /* initialize buffer with pattern */
  287.         if (!noDataCompare)
  288.             { 
  289.             for (i=0; i < 512; i++)
  290.                 buffer[i] = 'a';
  291.             }
  292.         /* 6 BYTE WRITE AND READ */
  293.         /* write the pattern to 1 sector */
  294.         if (scsiTestWrtSecs (pBlkDev, blockNumber, 1, buffer) == ERROR)
  295.             return (ERROR);
  296.         /* clear pattern from buffer */
  297. if (!noDataCompare)
  298.             bzero (buffer, 512);
  299.         /* read pattern from sector written to */
  300.         if (scsiTestRdSecs (pBlkDev, blockNumber, 1, buffer) == ERROR)
  301.             return (ERROR);
  302.         /* compare pattern */
  303.         if (!noDataCompare) 
  304.          {
  305.             for (i=0; i < 512; i++)
  306.                 {
  307.                 if (buffer[i] != 'a')
  308.                     {
  309.                     printf ("Failed reading disk. Incorrect patternn");
  310.                     return (ERROR);
  311.                     }
  312.                 }
  313.             }
  314. printf ("Pass disk READ/WRITE Testn");
  315.         }
  316.     
  317.     free (buffer);
  318.     
  319.     return (OK);
  320.     }
  321. /******************************************************************************
  322. *
  323. * scsiTestIoctl - test a device-specific control function
  324. *
  325. * This routine performs a specified function using a specified SCSI block
  326. * device. The command issued here is the TEST UNIT READY command. The command
  327. * is built and passed on to scsiIoctl() in scsiLib
  328. *
  329. * RETURNS: The status of the request, or ERROR if the request is unsupported
  330. */
  331. STATUS scsiTestIoctl 
  332.     (
  333.     SCSI_PHYS_DEV *pScsiPhysDev /* ptr to SCSI block device info */
  334.     )
  335.     {
  336.     SCSI_COMMAND myScsiCmdBlock;        /* SCSI command byte array */
  337.     SCSI_TRANSACTION myScsiXaction;     /* info on a SCSI transaction */
  338.     
  339.     /* build the test unit ready command */
  340.     if (scsiCmdBuild (myScsiCmdBlock, &myScsiXaction.cmdLength,
  341.       SCSI_OPCODE_TEST_UNIT_READY, pScsiPhysDev->scsiDevLUN,
  342.       FALSE, 0, 0, (UINT8) 0) == ERROR)
  343. return (ERROR);
  344.     
  345.     myScsiXaction.cmdAddress    = myScsiCmdBlock;
  346.     myScsiXaction.dataAddress   = NULL;
  347.     myScsiXaction.dataDirection = NONE;
  348.     myScsiXaction.dataLength    = 0;
  349.     myScsiXaction.addLengthByte = NONE;
  350.     myScsiXaction.cmdTimeout    = SCSI_TIMEOUT_5SEC;
  351.     
  352.     return (scsiIoctl (pScsiPhysDev, FIOSCSICOMMAND, (int) &myScsiXaction));
  353.     }
  354. /******************************************************************************
  355. *
  356. * validateParameterString - parse the paramater string
  357. *
  358. * This routine parses the parmater string and checks the validity of
  359. * each parameter.
  360. *
  361. * RETURNS: OK if passes, or ERROR if an error is encountered.
  362. */
  363. STATUS validateParameterString 
  364.     (
  365.     char * paramString,
  366.     char * test,                  /* which test to run: #1,#2,#3 or all */
  367.     int  * scsiBusId,             /* scsi id of the device */
  368.     int  * devLun,                /* lun id of the device  */
  369.     int  * testNo,                 /* which test to run: #1,#2,#3 or all */
  370.     int  * numIterationsRW,       /* how many times to run RW test      */
  371.     int  * numBlocks,             /* no. of blocks in block device */
  372.     int  * blkOffset              /* address of first block in volume */
  373.     )
  374.     {
  375.     sscanf (paramString, "%s %d %d %d %x %x", test, scsiBusId, devLun, 
  376.     numIterationsRW, numBlocks, blkOffset);
  377.     if ((*scsiBusId < 0) || (*scsiBusId > 7))
  378.        {
  379.        printf ("Invalid SCSI BUS ID: Range [0..7]n");
  380.        return (ERROR);
  381.        }
  382.     if ((*devLun < 0) || (*devLun > 7))
  383.        {
  384.        printf ("Invalid Logical Unitn");
  385.        return (ERROR);
  386.        }  
  387.     if ((((int) atoi (test) >= 1) && ((int) atoi (test) <= 3)) ||
  388.  (strcmp (test,"-a") == 0))
  389. {
  390. if (strcmp (test,"-a") == 0)
  391.     *testNo = 0;
  392. else
  393.     *testNo = (int) atoi (test);
  394. }
  395.     else
  396. {
  397. printf ("Invalid Test: Range [1..3 or -a]n");
  398. return (ERROR);
  399. }
  400.     if (*numIterationsRW < 0)
  401.        {
  402.        printf ("Invalid number of iterationsn");
  403.        return (ERROR);
  404.        }
  405.     if (*numBlocks < 0)
  406.        {
  407.        printf ("Innvalid Number of blocksn");
  408.        return (ERROR);
  409.        }
  410.     if (*blkOffset < 0)
  411.        {
  412.        printf ("Innvalid block addressn");
  413.        return (ERROR);
  414.        }
  415.     else
  416.       return (OK);
  417.     }
  418. /******************************************************************************
  419. *
  420. * scsiDiskTest - test direct access device (disk) 
  421. *
  422. * Three types of tests are available
  423. * 1. testCommonCmds ()
  424. * 2. testDirectRW ()
  425. * 3. testDirectCmdsAll ()
  426. *
  427. * Specifying 1 for the whichTests parameter invokes only test#1. Specifying
  428. * 2 invokes test#2 and 3 invokes test#3. Specifying  invokes all 3 tests
  429. * The RW test can be passed the numIterationsRW param, which runs that test
  430. * numIterationsRW times.
  431. *
  432. * RETURNS: OK if passes, or ERROR if an error is encountered.
  433. */
  434. STATUS scsiDiskTest
  435.     (
  436.     char * paramString
  437.     )
  438.     {
  439.     int scsiBusId;              /* scsi id of the device */
  440.     int devLun;                 /* lun id of the device  */
  441.     char *test;                /* which test to run: #1,#2,#3 or -[a] */
  442.     int testNo;                /* which test to run: #1,#2,#3 or all */
  443.     int numIterationsRW;  /* how many times to run RW test */
  444.     int numBlocks;              /* no. of blocks in block device */
  445.     int blkOffset;              /* address of first blcok in volume */
  446.     SCSI_PHYS_DEV *pPhysDev;
  447.     SCSI_BLK_DEV *pBlkDev;    
  448.     if (paramString == NULL)
  449.         {
  450.  printf ("Usage: n");
  451.  printf ("Example -> scsiDiskTest "-a 4 0 10 0x0000 0x0000"n");
  452.  printf ( "      "n");
  453.  printf ("       1. test        :  <#1,#2,#3 -[a]:runs all test>n");
  454.  printf ("       2. scsiBusId   :  <Target device ID>n");
  455.  printf ("       3. devLun      :  <Device Logical Unit ID>n");       
  456.  printf ("       4. Iterations  :  <how many times to run RW testsn");
  457.  printf ("       5. numBlocks   :  <no. of blocks in block device>n");
  458.  printf ("       6. blkOffset   :  <adrs of first block in volume>n");
  459.  printf ( "      "n");
  460.  return (ERROR);
  461.          }
  462.     test = (char *) malloc (4 * sizeof (char));
  463.     if (validateParameterString (paramString, test, &scsiBusId, &devLun, &testNo,
  464.  &numIterationsRW, &numBlocks, 
  465.  &blkOffset) == ERROR)
  466.       return (ERROR);
  467.     /* create physical SCSI device */
  468.     if ((pPhysDev=scsiPhysDevIdGet(0,scsiBusId,devLun))==(SCSI_PHYS_DEV *)NULL)
  469.         if ((pPhysDev=scsiPhysDevCreate(pSysScsiCtrl,scsiBusId,devLun,0,
  470. NONE,0,0,0)) == (SCSI_PHYS_DEV *) NULL)
  471.             {
  472.             printf ("pkTestOneUnit: scsiPhysDevCreate() failedn");
  473.             return (ERROR);
  474.             }
  475.     /* create logical SCSI device */
  476.     if ((pBlkDev = (SCSI_BLK_DEV *) scsiBlkDevCreate (pPhysDev, 0, 0)) == NULL)
  477.         {
  478.         printf ("pkTestOneUnit: scsiBlkDevCreate() failedn");
  479.         return (ERROR);
  480.         }
  481.     switch (testNo)
  482.         {
  483.         case 1 :
  484.             if (testCommonCmds (pPhysDev) == ERROR)
  485.           return (ERROR);
  486.             printf ("Pass disk COMMON COMMANDS testnn");
  487.     break;
  488.         case 2 :
  489.             if (testDirectRW (pPhysDev, pBlkDev, numIterationsRW, FALSE) 
  490. == ERROR)
  491.                 return (ERROR);
  492.             break;
  493. case 3 : 
  494.             if (testDirectCmdsAll (pPhysDev, pBlkDev,  FALSE) == ERROR)
  495.           return (ERROR);
  496.             printf ("Pass disk ALL COMMANDS testn");
  497.     break;
  498. case 0:
  499.             if (testCommonCmds (pPhysDev) == ERROR)
  500.         return (ERROR);
  501.             printf ("Pass disk COMMON COMMANDS testn");
  502.             if (testDirectRW (pPhysDev, pBlkDev, numIterationsRW, FALSE)
  503. == ERROR)
  504.           return (ERROR);
  505.             if (testDirectCmdsAll (pPhysDev, pBlkDev, FALSE) == ERROR)
  506.           return (ERROR);
  507.             printf ("Pass disk ALL COMMANDS testn");
  508.     break;
  509.         default :
  510.     break;
  511.         }
  512.     
  513.     return (OK);
  514.     }