home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -in_the_mag- / under_the_bonnet / scsi / spartan / newsformat / newstest.c < prev    next >
C/C++ Source or Header  |  1998-05-02  |  9KB  |  429 lines

  1. /*   SFormat version 2.0 by Paul Harker....written in Manx C v3.6    */
  2. /*    Stripped down by Mike Lundberg to just zero and check status,
  3.     added delay after select line is de-asserted, compilable on 
  4.     Lattice */
  5.        
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10.  
  11. typedef unsigned char byte;
  12.  
  13. byte RESET  = 128;        /*define CONTROL flags*/
  14. byte BUSY    = 64;
  15. byte REQUEST = 32;
  16. byte MSG     = 16;
  17. byte COMMAND  = 8;
  18. byte INPUT    = 4;
  19.  
  20. byte ACK     = 16;        /*define cmd flags*/
  21. byte PHASE    = 8;
  22. byte SELECT   = 4;
  23. byte BUS      = 1;
  24.  
  25.  
  26. byte *data;        /*pointer to SCSI data register*/
  27. byte *initCMD;        /*pointer to SCSI ICR register*/
  28. byte *targetCMD;         /*pointer to SCSI TCR register*/
  29. byte *control;        /*pointer to SCSI control register*/
  30. byte *status;        /*pointer to SCSI status register*/
  31.  
  32.  
  33. byte inbuff[100], outbuff[100], cmdbuff[10], statin, msg; /* SCSI IO storage */
  34.  
  35. unsigned int address, intrlv;
  36.  
  37. void main()
  38. {
  39.     void errorCHECK();
  40.     void readERROR();
  41.     void reZERO();
  42.     void unitRDY();
  43.     void modeSEL();
  44.     void doFORMAT();
  45.     void clearCMD();
  46.     void clearOUT();
  47.     void clearIN();
  48.     void goodmorning();
  49.     void scsi();
  50.     void doIO();
  51.     void waitREQ();
  52.     void doBASE();
  53.  
  54.  
  55.     int dummy;
  56.     int c;
  57.  
  58.                      /* define base offsets of registers*/ 
  59.  
  60.     data = 0x000001;
  61.     initCMD = 0x000003;
  62.     targetCMD = 0x000007;
  63.     control = 0x000009;
  64.     status = 0x00000B;
  65.  
  66.   
  67.     printf("\n  This utility is a Clone of STest with a delay after SEL\n");
  68.     printf("NO data will be destroyed.\n\n  Continue? (Y/N) :");
  69.  
  70.  
  71.  
  72.     c = getchar();            /* Change for Lattice */
  73.     c = toupper(c);
  74.     if(c != 'Y')
  75.        exit(200);
  76.  
  77. /*
  78.         if(toupper(getchar()) != 'Y')
  79.     {
  80.       printf("exiting program!\n");
  81.           exit(200);
  82.         }
  83. */
  84.     printf("\n   Base Address of interface :");
  85.       doBASE();
  86.  
  87.                       /*  Toss a Null  */
  88.     gets(dummy);
  89.  
  90.     printf("\n  SCSI address :");
  91.       address = getNumber(0,6);
  92. /*
  93.  
  94.     printf("  Interleave :");
  95.       intrlv = getNumber(1,27); 
  96.       intrlv = 2; */
  97.     printf("\n  Ready to Zero and check status.\n\n  Continue? (Y/N) :");
  98.  
  99.     c = getchar();        /* Change for Lattice */
  100.     c = toupper(c);
  101.     if(c != 'Y')
  102.        exit(200);
  103. /*
  104.         if (toupper(getchar()) != 'Y')
  105.             exit(200);
  106. */
  107.      printf("  Zeroing Drive..........");
  108.      fflush(stdout);    
  109.      reZERO();
  110.      errorCHECK();
  111.  
  112.      printf("  Checking Drive Ready...");
  113.      fflush(stdout);
  114.      unitRDY();
  115.      errorCHECK();
  116.      printf("\n Test Complete.\n");
  117.      Execute("wait 4",0,0);
  118. /*
  119.      printf("  Selecting Mode.........");
  120.      fflush(stdout);
  121.      modeSEL();
  122.      errorCHECK();
  123.  
  124.      printf("  Formatting.............");
  125.      fflush(stdout);
  126.      doFORMAT();
  127.      errorCHECK();
  128.      printf("\n Format Complete.\n");
  129. */
  130. }
  131.  
  132. void errorCHECK()    /* Check Status Byte and Report Error Data */
  133. {
  134. int count;
  135.  
  136. if (statin)
  137.     {  
  138.     if (statin == 8)
  139.        printf("\n SCSI Device Busy Error\n");
  140.     else 
  141.        {
  142.        readERROR();
  143.        printf("\n Completion Status Error #%d:",statin);
  144.        for (count = 0;count < 27 ;count ++) 
  145.            if (inbuff[count])
  146.                printf("\n Sense Error Byte #%d: %d",count,inbuff[count]);
  147.        }
  148.     Execute("wait 4",0,0);
  149.     exit(700);
  150.     }
  151. printf("OK\n");
  152. }
  153.  
  154. void readERROR()   /* Request Sense Command */
  155. {
  156. clearCMD();
  157. clearIN();
  158. cmdbuff[0] = 3;
  159. cmdbuff[4] = 27;       /* Read all possible sense data */
  160. scsi();
  161. }
  162.  
  163. /*  
  164.    future stuff eh dude?
  165. clearBUFF(&buff,elements)    /  Clear Specified Buffer  /
  166. int elements;
  167. byte buff[elements];
  168. {
  169. int count;
  170.  
  171. while (count = 0; count < elements; count++)
  172.     buff[count] = 0;
  173. }
  174. */
  175.  
  176. getNumber(lower,upper)   /* get a number between -32k to 32k  */
  177.  
  178. int lower, upper;
  179. {
  180. char input[10];
  181. int test = 0xffff;
  182.  
  183. while((test > upper) || (test < lower)){
  184.       gets(input);
  185.         test = atoi(input);
  186.           if ((test > upper) || (test < lower))
  187.              printf("\n  Bad Entry. Please try again  :");
  188.       }
  189. return test;
  190. }
  191.  
  192.  
  193.  
  194. void reZERO()
  195. {
  196.     clearCMD();
  197.     cmdbuff[0] = 1;
  198.     scsi();
  199. }    
  200.  
  201.  
  202. void unitRDY()
  203. {
  204.     clearCMD();
  205.     scsi();
  206. }
  207.  
  208.  
  209. void modeSEL()
  210. {
  211.     clearCMD();
  212.     clearOUT();
  213.  
  214.     cmdbuff[0] = 21;
  215.     cmdbuff[4] = 12;  /* parameter list length */
  216.  
  217.     outbuff[3] = 8;
  218.     outbuff[10] = 2;  /* high byte of block size -512 bytes- */
  219.  
  220.     scsi();
  221. }
  222.  
  223.  
  224. void doFORMAT()
  225. {
  226.  
  227.     clearCMD();
  228.     clearOUT();
  229.  
  230.     cmdbuff[0] = 4;
  231.     cmdbuff[4] = (byte) intrlv;
  232.  
  233.     scsi();   
  234. }
  235.  
  236.  
  237.  
  238. void clearCMD()   /*   Clear command buffer   */
  239. {
  240. int count;
  241.  
  242.    for(count=0;count <= 10 ;count++)
  243.        cmdbuff[count] = 0;
  244.  
  245. }
  246.  
  247.  
  248. void clearOUT()      /*   Clear output buffer    */
  249. {
  250. int count;
  251.  
  252.   for(count=0;count <= 100;count++)
  253.        outbuff[count] = 0;
  254. }
  255.  
  256.  
  257. void clearIN()       /*   Clear Input Data Buffer    */
  258. {
  259. int count;
  260.  
  261.    for(count = 0;count < 100;count++)
  262.       inbuff[count] = 0;
  263. }
  264.  
  265. void goodmorning()    /*wake up the controller*/
  266. {
  267. byte initiator = 128, target = (1 << address);
  268. long count;
  269.         
  270.     *initCMD = 0;                            /*clear the controller chip*/
  271.     *(initCMD + 2) = 0;
  272.     *control = 0;
  273.  
  274.     for(count = 0; *control & BUSY; count++){  /*if bus is busy, wait*/
  275.        if (count >= 100000){                /*wait for bus*/
  276.            printf("\n  SCSI bus BUSY error.\n\n");   
  277.            Execute("wait 4",0,0);
  278.        exit(100);
  279.            }
  280.        }
  281.  
  282.     *data = initiator | target;                   /*load scsi addresses */
  283.     *initCMD |= BUS;                         /*assert bus*/
  284.  
  285.     for(count = 0;count <60;count++);        /*wait 2 * 45 nanoseconds*/
  286.  
  287.     *initCMD |= SELECT;                      /*assert select*/
  288.  
  289.     for(count = 0; !(*control & BUSY); count++){
  290.         if (count >= 100000){            /*wait for busy from controller*/
  291.            printf("\n  No response from SCSI address #%d.\n\n",address);   
  292.              Execute("wait 4",0,0);
  293.              exit(100);
  294.            }
  295.         }
  296.     for(count = 0;count < 60;count++);
  297.     *initCMD &= ~SELECT;                     /*deassert select*/
  298.     for(count = 0;count < 60;count++);       /* mod by Mike Lundberg */
  299. }
  300.  
  301.  
  302.  
  303.  
  304. void scsi()          /* send Command and handle I/O */
  305. {
  306. byte dataout = 0, datain = 1, cmdout = 2,
  307.      instat = 3, msgin = 7;
  308.  
  309.     goodmorning();
  310.  
  311.     while (*control & BUSY){
  312.  
  313.        waitREQ();
  314.  
  315.        if (*control & COMMAND){                    /*cmd I/O?*/
  316.            if (*control & MSG){                    /*message?*/
  317.                if (*control & INPUT)              /*if message in*/
  318.                    doIO(msgin,&msg);             /*read it..msg out invalid*/
  319.            }
  320.  
  321.            else {                                 /*not msg..status or cmd*/
  322.                if (*control & INPUT)
  323.                    doIO(instat,&statin);          /*get status*/
  324.                else
  325.                    doIO(cmdout,cmdbuff);            /*send command*/
  326.           }
  327.        }
  328.  
  329.        else {                                    /*controller requests data I/O*/
  330.            if (*control & INPUT)                    /* input or output? */
  331.               doIO(datain,inbuff);                  /* input */
  332.            else
  333.               doIO(dataout,outbuff);                /* output */
  334.        }
  335.     }
  336. }
  337.  
  338.  
  339.  
  340. void doIO(mode,buffer)        /* Read-Send whatever the controller desires */
  341. byte mode, buffer[];
  342. {
  343. int index, count;
  344.  
  345.     *targetCMD = mode;                             /*what mode are we in*/
  346.  
  347.     for (index = 0;(*status & PHASE);index++){    /*while phase unchanged*/
  348.  
  349.          waitREQ();
  350.  
  351.          if (mode == 1 || mode == 3 || mode == 7)             /*if input*/
  352.             *(buffer + index) = *data;       /*get data*/
  353.  
  354.          else                                /*if output*/
  355.             *data = *(buffer + index);       /*write it*/
  356.  
  357.          *initCMD |= ACK;                  /*Perform ack*/
  358.  
  359.          while(*control & REQUEST);        /*wait for dropped req*/
  360.  
  361.          *initCMD &= ~ACK;                 /*drop ack*/
  362.  
  363.          for(count=0;count<4000;count++);  /*kill some time*/
  364.     }
  365.    *targetCMD = 0;
  366. }
  367.  
  368. void waitREQ()           /* Wait for REQ to be asserted */
  369. {
  370.     while(!(*control & REQUEST))
  371.         if(!(*control & BUSY) || !(*control & PHASE))
  372.             return;
  373. }
  374.             
  375. getADD(hex)
  376. char *hex;
  377. {
  378. int low, high, address;
  379.  
  380. high = unhex(*hex);
  381. low = unhex(*(hex+1));
  382. address = (high*16 + low);
  383. if (high < 0 || low < 0)
  384.     address = -1;
  385. return address;
  386. }
  387.  
  388. void doBASE()
  389. {
  390. char hex[20];
  391. int address = -1;
  392. unsigned long base;
  393.  
  394. while (address < 0)
  395.     {
  396.     scanf("%s",hex);
  397.     address = getADD(hex);
  398.     if (address < 0)
  399.         printf("\n  Bad Entry. Please try again  :");
  400.     }
  401. base = (address * 0x10000);
  402. data += base;          /*pointer to SCSI data register*/
  403. initCMD += base;       /*pointer to SCSI ICR register*/
  404. targetCMD += base;     /*pointer to SCSI TCR register*/
  405. control += base;       /*pointer to SCSI control register*/
  406. status += base;        /*pointer to SCSI status register*/
  407. }
  408.  
  409. unhex(ascii)
  410. char ascii;
  411. {
  412. int value;
  413. /*char tmp;*/
  414.  
  415. int c, tmp;
  416.  
  417. c = (int)ascii;
  418. tmp = toupper(c);
  419.  
  420. /*tmp = toupper(ascii);*/
  421. if (isalpha(tmp))
  422.     value = tmp-55;
  423. else if (isdigit(tmp))
  424.     value = tmp - 48;
  425. if (value > 15 || value < 0)
  426.     value = -1;
  427. return value;
  428. }
  429.