news@daver.bungi.com (10/12/90)
I would like some feedback regarding how to best locate and identify SCSI
units attached to the bus. To this end I have attached a code fragment
which seems to work with the SCSI devices that I have available.
I am exercising the code under DOS and am talking directly to the SCSI
host adapter. And the attached code produces the following output with my
devices attached:
device type vendor product
--------- ----------------- -------- ----------------
32 0:4:0 sequential access ADAPTEC
48 0:6:0 direct access MAXTOR XT-4380S
Total number of units found : 2
Total number of devices found : 2
In addition to comments on the logic of flushing out SCSI devices, I
would really appreciate receiving / seeing the response to the
INQUIRY command from other devices (eg. OMTI floppy controller, etc).
best regards,
johnc
/*===================================================================
scan.c Scan for all SCSI devices.
The INQUIRY command is used to identify SCSI devices.
The data format of the INQUIRY command has been expanded in SCSI-2
to include additional information. Unfornately the SCSI-1 data format
beyound byte 5 is generally vendor unique, however, in general the
vendor name seems to be located at or beyound data byte 0x08.
SCSI-1 data format:
0 | Peripheral Device Type |
-----|-----------------------------------------------------------------------|
1 | RMB | Device-Type Qualifier |
-----|-----------------------------------------------------------------------|
2 | ISO Version | ECMA Version | ANSI-Approved Version |
-----|-----------------------------------------------------------------------|
3 | Reserved |
-----|-----------------------------------------------------------------------|
[ stuff deleted ]
SCSI-2 data format:
0 | Peripheral Qualifier | Peripheral Device Type |
-----|-----------------------------------------------------------------------|
1 | RMB | Device-Type Modifier |
-----|-----------------------------------------------------------------------|
2 | ISO Version | ECMA Version | ANSI-Approved Version |
-----|-----------------------------------------------------------------------|
3 | AENC | TrmIOP | Reserved | Response Data Format |
-----|-----------------------------------------------------------------------|
[ stuff deleted ]
Beginning with SCSI-2, a response data format value of zero indicates
the INQUIRY data format is as specified in SCSI-1. A response data
format value of one indicates compatibility with some products that
were designed prior to the development of SCSI-2 (i.e., CCS).
A response data format value of two indicates that the data shall be
in the format specified in SCSI-2. Response data format values greater
than two are reserved.
According to SCSI-2, if the target is not capable of supporting a
device on a logical unit, data byte 0 should be set to 7Fh
(peripheral qualifier set to 011b and peripheral device type set to 1Fh).
However, on all SCSI-1 direct access devices that I have tested
return 00h for all LUNs. Therefore, we will make the assumption that
unless response data format is 2, direct access devices only support
LUN 0.
===================================================================*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include "scsi.h"
struct sccb ccb;
char buffer[ 512];
struct unit
{
int adapter_no; /* which host adapter */
int device_no; /* scsi_addr << 3 | lun */
int type; /* direct, seq, etc */
char *vendor_nm;
char *product_nm;
};
int nodevices;
int devices[ 8];
int nounits;
struct unit units[ 16];
main()
{
int i, j, ierr;
install_timer();
install_scsi_isr();
scsi_resetbus();
/* intialize the device array */
for (i = 0; i < 8; i++)
devices[ i] = -1;
/* initialize the unit array */
for (i = 0; i < 16; i++)
units[ i].device_no = -1;
/* locate the devices */
for (i = 0; i < 7; i++)
{
ierr = inquiry( i, 0, buffer, 36 );
if (ierr == CNOCONNECT)
continue;
devices[ nodevices++] = i;
}
/* for each located device, locate its logical units */
for (i = 0; i < nodevices; i++)
{
for (j = 0; j < 8; j++)
{
ierr = inquiry( devices[i], j, buffer, 36 );
if (ierr == COK)
{
record_unit( 0, devices[i], j, buffer, ccb.actuallen );
}
}
}
printf("\n");
show_scan();
printf("\n");
printf("Total number of units found : %d\n", nounits);
printf("Total number of devices found : %d\n", nodevices);
remove_timer();
remove_scsi_isr();
}
char *nm_devtypes[ ] =
{
"direct access",
"sequential access",
"printer",
"processor",
"WORM",
"CDROM",
"scanner",
"optical",
"media changer",
"communications"
};
show_scan()
{
int i;
struct unit *dv;
printf("device type vendor product\n");
printf("--------- ----------------- -------- ----------------\n");
for (i = 0; i < nounits; i++)
{
dv = &units[i];
printf("%02d %d:%d:%d ", dv->device_no, dv->adapter_no,
dv->device_no >> 3, dv->device_no & 7);
printf("%-17s ", nm_devtypes[ dv->type]);
if (dv->vendor_nm)
printf("%-8s ", dv->vendor_nm);
if (dv->product_nm)
printf("%-16s", dv->product_nm);
printf("\n");
}
}
char *get_vendor_nm( fmt, data, len )
int fmt; /* SCSI-1 = 0, CCS = 1, SCSI-2 = 2 */
char *data;
int len;
{
char ch;
char *s;
if (fmt > 2 || len < 8) return( NULL ); /* reserved value */
if (fmt == 0) /* SCSI-1, format vendor unique */
{
s = &data[ len];
while( !isalpha( *data) )
data++;
while( !isalpha( *s ))
s--;
*(++s) = 0;
return( strdup( data ) );
}
/* format standarized */
ch = data[ 8];
data[ 8] = 0;
for (s = &data[7]; *s == ' '; s--)
*s = 0;
data[ 8] = ch;
return( strdup( data ) );
}
char *get_product_nm( fmt, data, len )
int fmt;
char *data;
int len;
{
char *s, ch;
if (fmt == 0 || fmt > 2) return( NULL );
ch = data[ 16];
data[ 16] = 0;
for (s = &data[15]; *s == ' '; s--)
*s = 0;
data[ 16] = ch;
return( strdup( data ) );
}
record_unit( adapter, addr, lun, data, len )
int adapter; /* which host adapter */
int addr; /* SCSI address */
int lun; /* logical unit number */
char *data; /* inquiry response data */
int len; /* response length */
{
struct unit *dv;
int format;
/* A sufficient but not necessary test for non-existent LUN */
if (data[0] == 0x7F) return;
/* To stop certain direct access devices from reporting multiple
* LUNs. Such devices include Maxtor XT-4380S, CRC 94161-9 and
* Miniscribe 9380S.
*/
if (data[0] == 0 && data[3] = 0x01 && lun > 0) return;
dv = &units[ nounits++];
format = data[3] & 0x0F;
dv->adapter_no = adapter;
dv->device_no = addr << 3 | (lun & 0xFF);
dv->type = data[ 0] & 0x1F;
dv->vendor_nm = get_vendor_nm( format, &data[ 0x08], len - 0x08 );
dv->product_nm = get_product_nm(format, &data[ 0x10], len - 0x10 );
}
-- culberts@hplb.hpl.hp.com (Bruce Culbertson) (10/12/90)
Hi John, I appreciate your efforts to try to improve our SCSI driver. You may want to ignore the OMTI controller I am using, though. Guess what -- it does not do INQUIRY! Kind of defeats the whole scheme, doesn't it? The sooner I buy a new disk, the better. I am thinking of switching from being a home renter to being a home owner, so all things financial are on hold at the moment. Regards, Bruce