home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / devcon / milan_1991 / devcon91.2 / scsi / modesense.c < prev   
C/C++ Source or Header  |  1992-09-01  |  7KB  |  212 lines

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