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