From:	SMTP%"lauri@elwing.fnal.gov"  6-JUN-1994 10:16:11.39
To:	EVERHART
CC:	
Subj:	SCSI INQUIRY command to a SYSTEM disk -- can it be done?

From: lauri@fndcd.fnal.gov (Laurelin of Middle Earth)
X-Newsgroups: comp.os.vms
Subject: SCSI INQUIRY command to a SYSTEM disk -- can it be done?
Date: 1 Jun 1994 21:00:50 GMT
Organization: Fermi National Accelerator Lab
Lines: 93
Message-Id: <2sisu2$79n@fnnews.fnal.gov>
Reply-To: lauri@elwing.fnal.gov
Nntp-Posting-Host: dcd00.fnal.gov
To: Info-VAX@CRVAX.SRI.COM
X-Gateway-Source-Info: USENET

I am writing a program in C to send a SCSI INQUIRY command to various
devices so that I can read the vendor-specific information contained in
the inquiry data page.

The program works fine for all disks, 8mm tape drives, and CD players (in
short, all of the SCSI devices) on my system *except* the system disk. 
When I try the bootnode, the node crashes with FATALEXCPT (Fatal executive
or kernel mode exception).

I am hesitant to waste the bandwidth posting the entire code here, the
operative information is:

   struct {
	unsigned short status;		/* VMS status code */
	unsigned long  tfrcnt;		/* transfer count */
	unsigned : 8;
	unsigned char scsi_sts;		/* SCSI status code */
   } tgtiosb;				/* target io status block */

   struct {
    unsigned long opcode;               /* Opcode */
    variant_union {
        variant_struct {
            unsigned dir : 1;           /* Transfer direction, 1=READ/0=WRITE */
            unsigned dis : 1;           /* Enable disconnection */
            unsigned syn : 1;           /* Enable synchronous mode */
            unsigned dpr : 1;           /* Disable port retry */
        } flags_struct;
      unsigned long flags;
    } flags_union;
    unsigned char *cdbptr;              /* Pointer to SCSI command buffer */
    unsigned long cdblen;               /* Length of SCSI command */
    unsigned char *dataptr;             /* Pointer to SCSI data buffer */
    unsigned long datalen;              /* Length of SCSI data buffer */
    unsigned long padlen;               /* SCSI pad length */
    unsigned long phasetmo;             /* Phase change timeout */
    unsigned long discontmo;            /* Disconnection timeout */
    unsigned long unused[6];            /* Reserved */
   } tgtdesc;				/* target scsi descriptor */

   ...

/*
 Set up the descriptor with the SCSI information to be sent to the target.
 */
   tgtdesc.opcode = 1;
   tgtdesc.flags = 0;
   tgtdesc.dir = 1;
   tgtdesc.dis = 1;
   tgtdesc.cdbptr = (struct SCSI_INQ_CMD *) &inqcmd;
   tgtdesc.cdblen = sizeof inqcmd;
   tgtdesc.dataptr = (char *) &inqres;
   tgtdesc.datalen = sizeof inqres;
   tgtdesc.padlen = 0;
   tgtdesc.phasetmo = 60;
   tgtdesc.discontmo = 60;

   ...

   sts = sys$qiow( 0,
		tgtchan,		/* short, obtained via sys$assign */
		IO$_DIAGNOSE,		/* globalvalue */
		&tgtiosb,		/* see above */
		0, 0,
		&tgtdesc,		/* see above */
		sizeof tgtdesc,
		0, 0, 0, 0 )
   if (!(sts & 1)) sys$exit (sts);
   if (!(tgtiosb.status & 1)) sys$exit (tgtiosb.status);
   if (tgtiosb.scsi_sts) {
	printf ("Bad SCSI status returned: %02.2x\n", tgtiosb.scsi_sts);
	sys$exit (1);
   }

   ...

I can, of course, post more code details if they are necessary.  (Note
that inqcmd is a structure containing the SCSI INQUIRY data fields, and
inqres is a structure containing the results of the inquiry; I think that
these must be ok because they get the "right" answers when NOT on the
system disk).

The crash occurs at the $qiow.

Any ideas, clues, pointers, horror stories, etc., would be appreciated. 
Please email to me, I will post a summary.

-- lauri 
/-----------------------------------------------------------------------------\
| Lauri Loebel Carpenter        "All that is gold does not glitter,           |
| lauri@elwing.fnal.gov          Not all those who wander are lost..." - JRRT |
| #include <std.disclaimer>           /* I only speak for myself */           |
\-----------------------------------------------------------------------------/

