www.pudn.com > ScriptsSample.zip > SQUERY.C


/*--------------------------------------------------*/ 
/*                                                  */ 
/* Module SQUERY.C                                  */ 
/*                                                  */ 
/* Main module for SCSI inventory sample program.   */ 
/*                                                  */ 
/* Adapted from Symbios Logic                       */ 
/*    Software Development Kit                      */ 
/*                                                  */ 
/* Project: A Programmer's Guide to SCSI            */ 
/* Copyright (C) 1997, Brian Sawert.                */ 
/* All rights reserved.                             */ 
/*                                                  */ 
/*--------------------------------------------------*/ 
 
/*--------------------------------------------------*/ 
/*                                                  */ 
/* Description:                                     */ 
/*                                                  */ 
/* Get PCI BIOS information, print versions and     */ 
/* revision numbers.                                */ 
/*                                                  */ 
/* Print host adapter configuration info.           */ 
/*                                                  */ 
/* Poll SCSI bus for devices. Print results of      */ 
/* Inquiry command.                                 */ 
/*                                                  */ 
/* For disk devices, read capacity, read first      */ 
/* block, print block data.                         */ 
/*                                                  */ 
/*--------------------------------------------------*/ 
 
 
#include  
#include  
#include  
#include  
 
#include "spci.h" 
#include "s8xx.h" 
#include "sscsi.h" 
#include "gen_tool.h" 
 
 
/*---------- defines and macros ----------*/ 
 
// max target ID for Wide SCSI 
#define MAX_SCSI_ID     15 
 
// array size macro 
#define asize(x) (sizeof(x) / sizeof(*(x))) 
 
 
/*---------- global variables ----------*/ 
 
pci_bios pb; 
pci_device pd; 
c8xx_device cd; 
scsi_device sd[MAX_SCSI_ID + 1]; 
 
// needed for GEN_TOOL.C 
char *logfilename_ptr = NULL; 
 
// device types 
char *dev_name[] = { 
   "Direct-access", 
   "Sequential-access", 
   "Printer", 
   "Processor", 
   "Write-once", 
   "CD-ROM", 
   "Scanner", 
   "Optical memory", 
   "Medium changer", 
   "Communications" 
}; 
 
 
/*---------- external variables ----------*/ 
 
/*---------- local functions ----------*/ 
 
void print_block(BYTE *pbuf, WORD blk_size); 
 
 
/*---------- external functions ----------*/ 
 
 
#pragma argsused 
 
main(int argc, char *argv[]) 
{ 
   BYTE host_id; 
   WORD index; 
   int count; 
   int bstat, retry; 
   int retval; 
 
 
   if (PCI_GetPCIBIOSVersion(&pb) == PCI_NO_BIOS) { 
   // PCI BIOS not found 
      printf("PCI BIOS not found.\n"); 
      exit (1); 
   } 
 
   // got PCI BIOS info 
   printf("Found PCI BIOS version %02X.%02X.\n", 
      HIBYTE(pb.version), LOBYTE(pb.version)); 
   printf("Found %d PCI buses.\n", pb.lastbus + 1); 
   memset(&pd, 0, sizeof(pd)); 
 
   // search for specific PCI device 
   pd.vend_id = PCI_SYM_VENDOR_ID; 
   pd.dev_id = C825_DEVICE_ID; 
   pd.dev_index = 0; 
 
   if (PCI_FindDevice(&pd) == 0) { 
   // could not find PCI device 
      printf("PCI device not found.\n"); 
      exit(1); 
   } 
 
   // found PCI device 
   printf("Chip revision ID: %d\n", 
      pd.rev_id); 
   printf("I/O memory base: %08lX\n", 
      pd.mem_base); 
   printf("I/O address base: %08lX\n", 
      pd.io_base); 
   printf("SCRIPTS RAM base: %08lX\n", 
      pd.ram_base); 
   printf("Subsystem ID: %d\n", 
      pd.sub_id); 
   printf("Subsystem vendor ID: %d\n", 
      pd.sub_vend_id); 
   printf("ROM BIOS address: %08lX\n", 
      pd.rom_base); 
   printf("Interrupt number: %d\n", 
      pd.intl); 
 
   // get host SCSI ID 
   host_id = IORead8(pd.io_base + SCID) & 0x0F; 
   printf("Host SCSI ID: %d\n", host_id); 
 
   // initialize 825 chip 
   cd.scsi_id = host_id; 
   cd.dev_id = C825_DEVICE_ID; 
   cd.rev_id = C825_VERSION_ID; 
   cd.fifo_size_a = C8XX_53C825_FIFO_A; 
   cd.fifo_size_b = C8XX_53C825_FIFO_B; 
   cd.max_burst_a = C8XX_53C825_BRST_A; 
   cd.max_burst_b = C8XX_53C825_BRST_B; 
   cd.max_offset = C8XX_53C825_OFFSET; 
   cd.features = C8XX_53C825_FEAT; 
 
   if (init_8xx(&pd, &cd) == 0) { 
   // could not initialize chip 
      printf("Error initializing 53C825 chip.\n"); 
      exit (1); 
   } 
 
   if (init_buffers() == 0) { 
   // could not initialize buffers 
      printf("Error initializing memory buffers.\n"); 
      exit (1); 
   } 
 
   // do inventory of all devices on bus 
 
   for (count = 0; count <= MAX_SCSI_ID; count++) { 
   // loop through all SCSI devices 
 
      printf("\nChecking device at SCSI ID %d", count); 
 
      sd[count].targ_id = count; 
 
      if (count == host_id) { 
      // skip host adapter 
         printf(" - (Host adapter)"); 
         continue; 
      } 
 
      do { 
      // retry as needed 
         retry = 0; 
 
         // Test Unit Ready command 
         retval = test_unit_ready(&pd, &sd[count]); 
 
         switch (retval) { 
            case ERR_SUCCESS: 
               // Test Unit Ready succeeded 
 
               // do Device Inquiry command 
 
               sd[count].dev_type = 0xFF; 
 
               if (device_inquiry(&pd, &sd[count]) == 
                  ERR_SUCCESS) { 
               // command succeeded 
                  index = (datain_buf[0] & 0x1F); 
 
                  sd[count].dev_type = index; 
 
                  printf("\n   Device SCSI ID:   %d\n", 
                     sd[count].targ_id); 
                  printf("   Device type:      %d", 
                     index); 
                  printf(" (%s device)\n", 
                     (index < asize(dev_name)) ? 
                     dev_name[index] : "Unknown"); 
                  printf("   Vendor ID:        %.8s\n", 
                     &datain_buf[8]); 
                  printf("   Product ID:       %.8s\n", 
                     &datain_buf[16]); 
                  printf("   Product revision: %.8s\n", 
                     &datain_buf[32]); 
                  printf("   ANSI version:     %d\n", 
                     (datain_buf[2] & 0x07)); 
                  printf("   Wide 32 SCSI:     %s\n", 
                     (datain_buf[7] & 0x40) ? 
                     "Yes" : "No"); 
                  printf("   Wide 16 SCSI:     %s\n", 
                     (datain_buf[7] & 0x20) ? 
                     "Yes" : "No"); 
                  printf("   Synch transfer:   %s\n", 
                     (datain_buf[7] & 0x10) ? 
                     "Yes" : "No"); 
                  printf("   Linked commands:  %s\n", 
                     (datain_buf[7] & 0x10) ? 
                     "Yes" : "No"); 
                  printf("   Command queuing:  %s\n", 
                     (datain_buf[7] & 0x10) ? 
                     "Yes" : "No"); 
               } 
 
               if (sd[count].dev_type == 0x00) { 
               // direct access device 
                  bstat = read_capacity(&pd, &sd[count]); 
                   
                  if (bstat == ERR_SENSE) { 
                  // returned sense data 
 
                     if (sense_key == 0x02 && 
                        sense_asc == 0x3A && 
                        sense_ascq == 0x00) { 
                     // medium not present 
                        printf("   Medium not present.\n"); 
                     } 
                     else if (sense_key == 0x06 && 
                        sense_asc == 0x28 && 
                        sense_ascq == 0x00) { 
                     // medium changed - retry 
                        bstat = 
                           read_capacity(&pd, &sd[count]); 
                     } 
                  } 
 
                  if (bstat == ERR_SUCCESS) { 
                  // read disk drive capacity 
                     sd[count].blocks = 
                        ((DWORD) datain_buf[0] << 24) | 
                        ((DWORD) datain_buf[1] << 16) | 
                        ((DWORD) datain_buf[2] << 8) | 
                        (DWORD) datain_buf[3]; 
 
                     printf("   Block count:      %lu\n", 
                        sd[count].blocks); 
 
                     sd[count].blk_size = 
                        ((WORD) datain_buf[6] << 8) | 
                        (WORD) datain_buf[7]; 
 
                     printf( 
                        "   Block size:       %u bytes\n", 
                        sd[count].blk_size); 
 
                     // read first block on device 
                     if (read_block(&pd, &sd[count], 
                        0L, 1) == ERR_SUCCESS) { 
                     // block read succeeded 
                        printf("   First block:\n"); 
                        print_block(block_buf,  
                           sd[count].blk_size); 
                     } 
                  } 
               } 
 
               break; 
 
            case ERR_SENSE: 
               // Test Unit Ready returned sense data 
 
               if (sense_key == 0x02 && 
                  sense_asc == 0x29 && 
                  sense_ascq == 0x00) { 
               // device power up or reset 
                  retry = 1; 
               } 
 
               break; 
 
            case ERR_SELECT: 
            case ERR_TIMEOUT: 
               // timeout or select error 
               break; 
 
            case ERR_OTHER: 
            default: 
               // unhandled errors 
 
               printf(" - error.\n"); 
               break; 
         } 
      } while (retry); 
   } 
   printf("\n"); 
 
   exit(0); 
} 
 
 
 
void print_block(BYTE *pbuf, WORD blk_size) 
{ 
   WORD count; 
   int pad, row = 16; 
   char hbuf[80], cbuf[80]; 
   char *hptr, *cptr; 
 
 
   hptr = hbuf; 
   cptr = cbuf; 
 
   for (count = 0; count < blk_size; count++) { 
   // loop through block buffer 
      sprintf(hptr, "%02X ", pbuf[count]); 
      sprintf(cptr, "%c", 
         (isprint(pbuf[count]) ? pbuf[count] : '.')); 
 
      hptr += 3; 
      cptr++; 
 
      if (count % row == (row - 1)) { 
      // end this row 
         printf("   %04X  %s %s\n", 
            ((count / row) * row), hbuf, cbuf); 
         hptr = hbuf; 
         cptr = cbuf; 
      } 
   } 
 
   if ((count - 1) % row != (row - 1)) { 
   // print remainder 
      pad = (row - (count % row)) * 3; 
      memset(hptr, ' ', pad); 
      hptr[pad] = '\0'; 
 
      printf("   %04X  %s %s\n", 
         ((count / row) * row), hbuf, cbuf); 
   } 
}