/* *******************************
 * *                             *
 * *  IRIS SCSI inquiry program  *
 * *                             *
 * *******************************
 * file: utils/dsp/inquiry.c
 *      
 *               COPYRIGHT (c) 1998, 1999, 2001, 2003 BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.  
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED. 
 */
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#ifdef IRIX
#include <sys/dsreq.h>
#endif
#ifdef HPUX
#include <sys/scsi.h>
#endif
#ifdef AIX
#include <sys/scsi.h>
#include <sys/lockf.h>
#define GK_IBM_IOCMD (2)
#endif

#include "sigtypes.h"
#ifndef LINUX
#include "dsp.h"
#endif  /* #ifndef LINUX */

#include "dsp_lib.h"

#define GK_SCSI_INQUIRY   (0x12)     /* SCSI Inquiry Op Code (7.2.5) */

/* This program allows reading all the data from a SCSI inquiry command.
 */
int main( int argc_a, char *argv_a[] )
{
  char sdevice[PATHNAME_SIZE];

  UINT1 gkdata[255] ;  /* Max size 256, because size must fit in 1 byte */
  char string[100];
  UINT2 ilength;
  SINT4 fildes, ii;

  /* Process arguments from the command line
   */
  if (argc_a < 2)
    {
      printf( "Usage: inquiry device\n" );
      exit( EXIT_FAILURE );
    }
  strncpy( sdevice, argv_a[1], PATHNAME_SIZE-1 );
  sdevice[PATHNAME_SIZE-1]=0;

  fildes = open( sdevice, O_RDWR, 0 ) ;
  if( fildes < 0 )
    {
      perror( "open" );
      exit( EXIT_FAILURE );
    }
  
  /* Send an inquiry command to the SCSI target as the first step in making
   * a connection with it.
   */
  memset( gkdata, 0, sizeof(gkdata) ) ;
  
  
#ifdef AIX /* ------------------------- IBM Code ------------------------- */
  {
    struct sc_iocmd gkdesc ; SINT4 ii ;
    
    memset( &gkdesc, 0, sizeof(gkdesc) ) ;
    gkdesc.data_length    = sizeof(gkdata) ;
    gkdesc.buffer         = (char *)&gkdata ;
    gkdesc.timeout_value  = DSP_TIMEOUT_MS / 1000 ;
    gkdesc.flags          = B_READ ;
    gkdesc.command_length = 6 ;
    
    gkdesc.scsi_cdb[0] = GK_SCSI_INQUIRY ;
    gkdesc.scsi_cdb[4] = sizeof(gkdata) ;
    
    ii = ioctl( fildes, GK_IBM_IOCMD, &gkdesc ) ;
    if( ii < 0 )
      {
	perror( "ioclt" ) ;
	exit( EXIT_FAILURE);
      }
  }
#endif /* #ifdef AIX */

#ifdef HPUX /* ------------------------- HP Code ------------------------- */
  {
    struct sctl_io gkdesc ; SINT4 ii ;
    
    memset( &gkdesc, 0, sizeof(gkdesc) ) ;
    gkdesc.data_length    = sizeof(gkdata) ;
    gkdesc.data           = (void *)&gkdata ;
    gkdesc.max_msecs      = DSP_TIMEOUT_MS ;
    gkdesc.flags          = SCTL_READ ;
    gkdesc.cdb_length     = 6 ;
    
    gkdesc.cdb[0]  = GK_SCSI_INQUIRY ;
    gkdesc.cdb[4]  = sizeof(gkdata) ;
    
    ii = ioctl( fildes, SIOC_IO, &gkdesc ) ;
    if( ii < 0 )
      {
	perror( "ioctl" );
	exit( EXIT_FAILURE) ;
      }
  }
#endif /* #ifdef HPUX */
  
#ifdef IRIX /* ------------------------- SGI Code ------------------------- */
  {
    struct dsreq gkdesc ; SINT4 ii ; UINT1 command[6] ;
    
    memset( &gkdesc, 0, sizeof(gkdesc) ) ;
    gkdesc.ds_flags       = DSRQ_READ | DSRQ_DISC ;
    gkdesc.ds_time        = DSP_TIMEOUT_MS ;
    gkdesc.ds_cmdbuf      = (caddr_t)&command ;
    gkdesc.ds_cmdlen      = sizeof(command) ;
    gkdesc.ds_databuf     = (caddr_t)&gkdata ;
    gkdesc.ds_datalen     = sizeof(gkdata) ;
    
    memset( &command, 0, sizeof(command) ) ;
    command[0]  = GK_SCSI_INQUIRY ;
    command[4]  = sizeof(gkdata) ;
    
    ii = ioctl( fildes, DS_ENTER, &gkdesc ) ;
    if( ii < 0 ) 
      {
	perror( "ioctl" ) ;
	exit(EXIT_FAILURE) ;
      }
  }
#endif /* #ifdef IRIX */
  
  /* Print results
   */
  ilength = gkdata[4]+4;
  printf( "Inquiry data size: %d\n", ilength );
  for (ii=0; ii<8; ii++)
    {
      if (ilength>ii) printf( "Byte %d: 0x%2x\n", ii, gkdata[ii] );
    }
  if (ilength<=8) exit(EXIT_SUCCESS);
  memcpy( string, &gkdata[8], 8 ); string[8] = 0;
  printf( "Vendor ID: '%s'\n", string );

  if (ilength<=16) exit(EXIT_SUCCESS);
  memcpy( string, &gkdata[16], 16 ); string[16] = 0;
  printf( "Product ID: '%s'\n", string );

  if (ilength<=32) exit(EXIT_SUCCESS);
  memcpy( string, &gkdata[32], 4 ); string[4] = 0;
  printf( "Product Revision: '%s'\n", string );

  if (ilength<=36) exit(EXIT_SUCCESS);
  memcpy( string, &gkdata[36], 20 ); string[20] = 0;
  printf( "Vendor Specific: '%s'\n", string );

  if (ilength<=96) exit(EXIT_SUCCESS);
  memcpy( string, &gkdata[96], 99 ); string[99] = 0;
  printf( "Vendor Specific: '%s'\n", string );

  exit(EXIT_SUCCESS) ;
}
