Article View: comp.sys.amiga.tech
Article #13165Re: scsidisk.h and scsidirect.device - Inquiry example!
From: ~XT6561110~Mike Hall~C24~M26a~60...
Date: Tue, 19 Dec 1989 16:54
Date: Tue, 19 Dec 1989 16:54
251 lines
6952 bytes
6952 bytes
= In article <1753@agora.UUCP> billsey@.UUCP (Bill Seymour) writes:
= >In article <1842@sauron.Columbia.NCR.COM: stevem@sauron.UUCP (Steve McClure) writes:
= This is good news, thanks Bill. I had talked to Supra and was told flatly
= there was no example code. I did however have minimal success using the
= device. SCSI devices responded, but I did not figure out how to read the
= results of an Inquiry.
In the back of Xetec's manual, they list a one-page routine to do "SCSI
direct". They use the "harddisk.device", however. Is that going to be
non-standard?
As for reading/interpreting the Inquiry data... I'm glad you asked! I was
going to post this today, and you've given me a nice lead-in.. Thank you!
What follows is a shell archive of "inq.c" - the guy that examines the
Inquiry response, and two other files. I didn't like the way that Xetec's
implementation of accessing the SCSI device was so dense: open everything,
do it, close everything. (I want to write a tape application that actually
works - unlike their own product...grrr.) Sooo... I chopped it up into
OpenSCSI, DoSCSI, and CloseSCSI. I've also invented a new structure to
hold all the crap - SCSIcb (SCSI command block).
I would appreciate near-lethal comments and criticisms of this code. It
wasn't written in the wee hours, but it _was_ getting pretty late... :-)
Thanks!
--- cut here --- --- --- --- --- --- --- --- --- ---
# The rest of this file is a shell script which will extract:
# inq.c scsinfc.c scsinfc.h
echo x - inq.c
cat >inq.c <<'!Funky!Stuff!'
/*
* SCSI Device Inquiry
*/
#include <exec/types.h>
#include <exec/io.h>
#include <devices/scsidisk.h>
#include <FastTrak.h>
#include "SCSInfc.h"
#include <stdio.h>
#include <string.h>
#define MAX_PD_TYPE 10
char *pdtypes[] = {
"disk", "tape", "printer", "processor",
"worm", "rodisk", "scanner", "optical",
"changer", "communication", "(unknown)"
};
#define INQRESP 128
long resp[INQRESP/4]; /* Inquiry response - watch alignment! */
char cdb[10] = /* SCSI command itself (ditto!) */
{ 0x12, 0, 0, 0, INQRESP, 0, 0, 0, 0, 0 };
struct SCSIcb scb; /* general SCSI control block */
void showinfo(unit, params)
short unit;
char params[];
{
char vendor[10], product[18], prodrev[6];
int rmb, devtype;
devtype = params[0];
if ( devtype < 0 || devtype > MAX_PD_TYPE )
devtype = MAX_PD_TYPE+1;
rmb = params[1]&0x80;
strncpy(vendor, ¶ms[8], 8);
vendor[8] = '\0';
strncpy(product, ¶ms[16], 16);
product[16] = '\0';
strncpy(prodrev, ¶ms[32], 4);
prodrev[4] = '\0';
printf(" \033[1m%d\033[0m: %s %s \033[7m%s\033[0m \033[7m%s\033[0m \033[7m%s\033[0m\n",
unit,
rmb ? "Removable" : "Non-removable",
pdtypes[devtype],
vendor, product, prodrev);
}
void showfail(unit, r)
short unit, r;
{
printf(" \033[1m%d\033[0m: \033[3;33mfail, %s\033[0;31m\n",
unit, fterrmsg(r));
}
void inquire(unit)
int unit;
{
int r;
scb.unit = unit;
scb.SCmd.scsi_Data = (APTR) resp;
scb.SCmd.scsi_Length = INQRESP;
scb.SCmd.scsi_Command = cdb;
scb.SCmd.scsi_CmdLength = 6;
scb.SCmd.scsi_Flags = SCSIF_READ;
if ( r = OpenSCSI(&scb) ) {
showfail(unit, r);
return;
}
else if ( (r = DoSCSI(&scb)) ) {
showfail(unit, r);
} else {
showinfo(unit, resp);
}
CloseSCSI(&scb);
}
void main(argc,argv)
int argc;
char *argv[];
{
int unit;
if ( argc > 2 || *argv[1] == '?' || /* bad args */
(*argv[1] == '-' && argv[1][1] == '?') ) { /* (poor code!) */
printf("Usage: %ls <unit>\n",argv[0]);
exit(FALSE);
}
else if ( argc == 1 ) { /* no args: do all */
for ( unit = 0; unit <= 7; unit++ )
inquire(unit);
}
else { /* one arg: do one */
unit = atoi(argv[1]);
if ( unit < 0 || unit > 7 ) {
printf("Use: %ls <unit>\n", argv[0]);
exit(FALSE);
}
inquire(unit);
}
}
!Funky!Stuff!
echo x - scsinfc.c
cat >scsinfc.c <<'!Funky!Stuff!'
/*
* SCSI general interface routines
*/
#include <exec/types.h>
#include <exec/io.h>
#include <devices/scsidisk.h>
#include <FastTrak.h>
#include "scsinfc.h"
int OpenSCSI(scb)
struct SCSIcb *scb;
{
int ret;
scb->flags = 0;
if ( scb->Port = (struct MsgPort *)CreatePort("ft_Tools",0) ) {
if ( scb->Req = (struct IOStdReq *)CreateStdIO(scb->Port) ) {
if ( ret = OpenDevice("harddisk.device",
scb->unit, scb->Req, 0) ) {
DeleteStdIO(scb->Req);
DeletePort(scb->Port);
} else {
scb->flags = 1;
scb->Req->io_Command = 28;
scb->Req->io_Data = (APTR)&scb->SCmd;
scb->Req->io_Length = sizeof(struct SCSICmd);
}
}
}
return ret;
}
void CloseSCSI(scb)
struct SCSIcb *scb;
{
if ( scb->flags ) {
AbortIO(scb->Req);
WaitIO(scb->Req);
CloseDevice(scb->Req);
scb->flags = 0;
}
if ( scb->Req ) {
DeleteStdIO(scb->Req);
scb->Req = NULL;
}
if ( scb->Port ) {
DeletePort(scb->Port);
scb->Port = NULL;
}
}
int DoSCSI(scb)
struct SCSIcb *scb;
{
DoIO(scb->Req);
/* Or... SendIO(req); WaitIO(req); */
/* Actual = scb->SCmd.scsi_Actual; */
return (int) scb->SCmd.scsi_Status;
}
/*
* Return error message given FastTrak error code
*/
char *fterrmsg(err)
int err;
{
switch (err) {
case FTERR_SelfUnit: return "cannot issue SCSI command to self";
case FTERR_DMA: return "DMA error";
case FTERR_Phase: return "illegal or unexpected SCSI phase";
case FTERR_Parity: return "SCSI parity error";
case FTERR_SelTimeout: return "select timed out";
case FTERR_BadStatus: return "status and/or sense error";
case FTERR_NoBoard: return "open failed for non-existant board";
default: return "unknown error";
}
}
!Funky!Stuff!
echo x - scsinfc.h
cat >scsinfc.h <<'!Funky!Stuff!'
/*
* definitions for SCSInfc.c
*/
struct SCSIcb { /* SCSI control block */
short flags; /* open or not */
short unit; /* which SCSI unit this is for */
struct IOStdReq *Req; /* IORequest */
struct MsgPort *Port; /* and Message Port */
struct SCSICmd SCmd; /* and the SCSI Command ptrs */
};
int OpenSCSI(struct SCSIcb *);
void CloseSCSI(struct SCSIcb *);
int DoSCSI(struct SCSIcb *);
char *fterrmsg(int);
!Funky!Stuff!
------ that's all ---
Mike Hall att!cuuxb!migh migh@cuuxb.att.com
Technical Details
Message-ID:
<4375@cuuxb.ATT.COM>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!apple!rutgers!att!cuuxb!mighReferences:
<1842@sauron.Columbia.NCR.COM> <1753@agora.UUCP> <1850@sauron.Columbia.NCR.COM>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!apple!rutgers!att!cuuxb!migh From: migh@cuuxb.ATT.COM (~XT6561110~Mike Hall~C24~M26a~6029~) Newsgroups: comp.sys.amiga.tech Subject: Re: scsidisk.h and scsidirect.device - Inquiry example! Summary: sample code, critique requested Keywords: source, SCSI Message-ID: <4375@cuuxb.ATT.COM> Date: 19 Dec 89 16:54:15 GMT References: <1842@sauron.Columbia.NCR.COM> <1753@agora.UUCP> <1850@sauron.Columbia.NCR.COM> Reply-To: migh@cuuxb.UUCP Mike Hall Organization: AT&T Computer Systems, Lisle, IL Lines: 251