📄 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 <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <ctype.h>
#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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -