home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 1.2 / amidev_cd_12.iso / reference_library / devices / dev_examples / scsi_direct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-20  |  9.4 KB  |  238 lines

  1. /*
  2.  * SCSI_Direct.c
  3.  *
  4.  * The following program demonstrates the use of the HD_SCSICmd to send a
  5.  * MODE SENSE to a unit on the requested device (default scsi.device).  This
  6.  * code can be easily modified to send other commands to the drive.
  7.  *
  8.  * Compile with SAS C 5.10  lc -b1 -cfistq -v -y -L
  9.  *
  10.  * Run from CLI only
  11.  */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <exec/io.h>
  16. #include <devices/scsidisk.h>
  17. #include <dos/dosextens.h>
  18.  
  19. #include <clib/exec_protos.h>
  20. #include <clib/alib_protos.h>
  21.  
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24.  
  25. #ifdef LATTICE
  26. int CXBRK(void) { return(0); }  /* Disable SAS CTRL/C handling */
  27. int chkabort(void) { return(0); }  /* really */
  28. #endif
  29.  
  30. #define BUFSIZE 256
  31.  
  32. UBYTE *buffer;                  /* a data buffer used for mode sense data */
  33. struct IOStdReq SCSIReq;        /* a standard IORequest structure */
  34. struct SCSICmd Cmd;             /* where the actual SCSI command goes */
  35. UBYTE  Sense[20];               /* buffer for request sense data */
  36. struct MsgPort Port;            /* our ReplyPort */
  37.  
  38. void ShowSenseData(void);
  39.  
  40. static UBYTE TestReady[] = { 0,0,0,0,0,0 };     /* not used but here for  */
  41. static UBYTE StartUnit[] = { 0x1b,0,0,0,1,0 };  /* illustration of other  */
  42. static UBYTE StopUnit[] =  { 0x1b,0,0,0,0,0 };  /* commands.              */
  43.  
  44. static UBYTE ModeSense[]={ 0x1a,0,0xff,0,254,0 }; /* the command being sent */
  45.  
  46. void main(int argc, char **argv)
  47. {
  48. int unit,tval,i;
  49. char *dname = "scsi.device";
  50. UBYTE *tbuf;
  51.  
  52. if ((argc < 2) || (argc > 3))
  53.     {
  54.     printf("Usage: %s unit [xxxx.device]\n",argv[0]);
  55.     exit(100);
  56.     }
  57.  
  58. unit = atoi( argv[1] );
  59. if (argc == 3)
  60.     dname = argv[2];
  61.  
  62. buffer = (UBYTE *) AllocMem(BUFSIZE, MEMF_PUBLIC|MEMF_CLEAR);
  63.  
  64. if (!buffer)
  65.     {
  66.     printf("Couldn't get memory\n");
  67.     exit(100);
  68.     }
  69.  
  70. Port.mp_Node.ln_Pri = 0;                        /* setup the ReplyPort */
  71. Port.mp_SigBit      = AllocSignal(-1);
  72. Port.mp_SigTask     = (struct Task *)FindTask(0);
  73. NewList( &(Port.mp_MsgList) );
  74.  
  75. SCSIReq.io_Message.mn_ReplyPort = &Port;
  76.  
  77. if (OpenDevice( dname, unit, &SCSIReq, 0))
  78.     {
  79.     printf("Couldn't open unit %ld on %s\n",unit,dname);
  80.     FreeMem( buffer,BUFSIZE );
  81.     exit(100);
  82.     }
  83.  
  84. SCSIReq.io_Length  = sizeof(struct SCSICmd);
  85. SCSIReq.io_Data    = (APTR)&Cmd;
  86. SCSIReq.io_Command = HD_SCSICMD;        /* the command we are sending   */
  87.  
  88. Cmd.scsi_Data = (UWORD *)buffer;        /* where we put mode sense data */
  89. Cmd.scsi_Length = 254;          /* how much we will accept      */
  90. Cmd.scsi_CmdLength = 6;         /* length of the command        */
  91. Cmd.scsi_Flags = SCSIF_AUTOSENSE|SCSIF_READ;
  92.                                 /* do automatic REQUEST_SENSE   */
  93.                                 /* set expected data direction  */
  94. Cmd.scsi_SenseData =(UBYTE *)Sense;     /* where sense data will go     */
  95. Cmd.scsi_SenseLength = 18;              /* how much we will accept      */
  96. Cmd.scsi_SenseActual = 0;               /* how much has been received   */
  97.  
  98. Cmd.scsi_Command=(UBYTE *)ModeSense;/* issuing a MODE_SENSE command     */
  99. DoIO( &SCSIReq );                       /* send it to the device driver */
  100.  
  101. if (Cmd.scsi_Status)
  102.     ShowSenseData();      /* if bad status then show it */
  103.  
  104. else
  105.     {
  106.     printf("\nBlock descriptor header\n");
  107.     printf("=======================\n");
  108.     printf("Mode Sense data length  = %d\n",(short)buffer[0]);
  109.     printf("Block descriptor length = %d\n",(short)buffer[3]);
  110.     tbuf = &buffer[4];
  111.     printf("Density code            = %d\n",(short)tbuf[0]);
  112.     tval = (tbuf[1]<<16) + (tbuf[2]<<8) + tbuf[3];
  113.     printf("Number of blocks        = %ld\n",tval);
  114.     tval = (tbuf[5]<<16) + (tbuf[6]<<8) + tbuf[7];
  115.     printf("Block size              = %ld\n",tval);
  116.  
  117.     tbuf += buffer[3];          /* move to page descriptors */
  118.  
  119.     while ((tbuf - buffer) < buffer[0])
  120.            {
  121.  
  122.            switch (tbuf[0] & 0x7f)
  123.                    {
  124.                    case 1:
  125.                           printf("\nError Recovery Parameters\n");
  126.                           printf("=========================\n");
  127.                           printf("Page length             = %d\n",(short)tbuf[1]);
  128.                           printf("DISABLE CORRECTION      = %d\n",(short)tbuf[2]&1);
  129.                           printf("DISABLE XFER ON ERROR   = %d\n",(short)(tbuf[2]>>1)&1);
  130.                           printf("POST ERROR              = %d\n",(short)(tbuf[2]>>2)&1);
  131.                           printf("ENABLE EARLY CORRECTION = %d\n",(short)(tbuf[2]>>3)&1);
  132.                           printf("READ CONTINUOUS         = %d\n",(short)(tbuf[2]>>4)&1);
  133.                           printf("TRANSFER BLOCK          = %d\n",(short)(tbuf[2]>>5)&1);
  134.                           printf("AUTO READ REALLOCATION  = %d\n",(short)(tbuf[2]>>6)&1);
  135.                           printf("AUTO WRITE REALLOCATION = %d\n",(short)(tbuf[2]>>7)&1);
  136.                           printf("Retry count             = %d\n",(short)tbuf[3]);
  137.                           printf("Correction span         = %d\n",(short)tbuf[4]);
  138.                           printf("Head offset count       = %d\n",(short)tbuf[5]);
  139.                           printf("Data strobe offset count= %d\n",(short)tbuf[6]);
  140.                           printf("Recovery time limit     = %d\n",(short)tbuf[7]);
  141.  
  142.                           tbuf += tbuf[1]+2;
  143.                           break;
  144.  
  145.                    case 2:
  146.                           printf("\nDisconnect/Reconnect Control\n");
  147.                           printf("============================\n");
  148.                           printf("Page length             = %d\n",(short)tbuf[1]);
  149.                           printf("Buffer full ratio       = %d\n",(short)tbuf[2]);
  150.                           printf("Buffer empty ratio      = %d\n",(short)tbuf[3]);
  151.                           tval = (tbuf[4]<<8)+tbuf[5];
  152.                           printf("Bus inactivity limit    = %d\n",tval);
  153.                           tval = (tbuf[6]<<8)+tbuf[7];
  154.                           printf("Disconnect time limit   = %d\n",tval);
  155.                           tval = (tbuf[8]<<8)+tbuf[9];
  156.                           printf("Connect time limit      = %d\n",tval);
  157.                           tval = (tbuf[10]<<8)+tbuf[11];
  158.                           printf("Maximum burst size      = %d\n",tval);
  159.                           printf("Disable disconnection   = %d\n",(short)tbuf[12]&1);
  160.  
  161.                           tbuf += tbuf[1]+2;
  162.                           break;
  163.  
  164.                    case 3:
  165.                           printf("\nDevice Format Parameters\n");
  166.                           printf("========================\n");
  167.                           printf("Page length             = %d\n",(short)tbuf[1]);
  168.                           tval = (tbuf[2]<<8)+tbuf[3];
  169.                           printf("Tracks per zone         = %d\n",tval);
  170.                           tval = (tbuf[4]<<8)+tbuf[5];
  171.                           printf("Alternate sectors/zone  = %d\n",tval);
  172.                           tval = (tbuf[6]<<8)+tbuf[7];
  173.                           printf("Alternate tracks/zone   = %d\n",tval);
  174.                           tval = (tbuf[8]<<8)+tbuf[9];
  175.                           printf("Alternate tracks/volume = %d\n",tval);
  176.                           tval = (tbuf[10]<<8)+tbuf[11];
  177.                           printf("Sectors per track       = %d\n",tval);
  178.                           tval = (tbuf[12]<<8)+tbuf[13];
  179.                           printf("Bytes per sector        = %d\n",tval);
  180.                           tval = (tbuf[14]<<8)+tbuf[15];
  181.                           printf("Interleave              = %d\n",tval);
  182.                           tval = (tbuf[16]<<8)+tbuf[17];
  183.                           printf("Track skew factor       = %d\n",tval);
  184.                           tval = (tbuf[18]<<8)+tbuf[19];
  185.                           printf("Cylinder skew factor    = %d\n",tval);
  186.  
  187.                           tbuf += tbuf[1]+2;
  188.                           break;
  189.  
  190.                    case 4:
  191.                           printf("\nDrive Geometry Parameters\n");
  192.                           printf("=========================\n");
  193.                           printf("Page length             = %d\n",(short)tbuf[1]);
  194.                           tval = (tbuf[2]<<16)+(tbuf[3]<<8)+tbuf[4];
  195.                           printf("Number of cylinders     = %ld\n",tval);
  196.                           printf("Number of heads         = %d\n",(short)tbuf[5]);
  197.                           tval = (tbuf[6]<<16)+(tbuf[6]<<8)+tbuf[8];
  198.                           printf("Start write precomp     = %ld\n",tval);
  199.                           tval = (tbuf[9]<<16)+(tbuf[10]<<8)+tbuf[11];
  200.                           printf("Start reduced write     = %ld\n",tval);
  201.                           tval = (tbuf[12]<<8)+tbuf[13];
  202.                           printf("Drive step rate         = %d\n",tval);
  203.                           tval = (tbuf[14]<<16)+(tbuf[15]<<8)+tbuf[16];
  204.                           printf("Landing zone cylinder   = %ld\n",tval);
  205.  
  206.                           tbuf += tbuf[1]+2;
  207.                           break;
  208.  
  209.                    default:
  210.                            printf("\nVendor Unique Page Code %2x\n",(short)tbuf[0]);
  211.                            printf("==========================\n");
  212.                            for (i=0; i<=tbuf[1]+1; i++ )
  213.                                 printf("%x ",(short)tbuf[i]);
  214.  
  215.                            printf("\n");
  216.                            tbuf += tbuf[1]+2;
  217.                    }
  218.            }
  219.     }
  220.  
  221. CloseDevice( &SCSIReq );
  222. FreeMem( buffer, BUFSIZE );
  223. FreeSignal(Port.mp_SigBit);
  224. }
  225.  
  226.  
  227.  
  228. void ShowSenseData(void)
  229. {
  230. int i;
  231.  
  232. for (i=0; i<18; i++)
  233.      printf("%x ",(int)Sense[i]);
  234.  
  235. printf("\n");
  236. }
  237.  
  238.