home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Developer CD v1.2
/
amidev_cd_12.iso
/
devcon
/
milan_1991
/
devcon91.2
/
scsi
/
modesense.c
< prev
Wrap
C/C++ Source or Header
|
1992-09-01
|
7KB
|
212 lines
/*
* Copyright (C) 1990 Commodore-Amiga, Inc.
* All rights reserved
*/
/*
* The following program demonstrates the use of the HD_SCSICmd to send a
* MODE SENSE to a unit on the requested device (default scsi.device). This
* code can be easily modified to send other commands to the drive.
*
* compile under Lattice using 'lc -cfist -L modesense'
*/
#include <stdio.h>
#include <stdlib.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <devices/timer.h>
#include <devices/scsidisk.h>
#include <libraries/dosextens.h>
#include <proto/exec.h>
#define BUFSIZE 256
UBYTE *buffer; /* a data buffer used for mode sense data */
struct IOStdReq SCSIReq; /* a standard IORequest structure */
struct SCSICmd Cmd; /* where the actual SCSI command goes */
UBYTE Sense[20]; /* buffer for request sense data */
struct MsgPort Port; /* our ReplyPort */
void ShowSenseData(void);
static UBYTE TestReady[] = { 0,0,0,0,0,0 }; /* not used but here for */
static UBYTE StartUnit[] = { 0x1b,0,0,0,1,0 }; /* illustration of other */
static UBYTE StopUnit[] = { 0x1b,0,0,0,0,0 }; /* commands. */
static UBYTE ModeSense[]={ 0x1a,0,0xff,0,254,0 }; /* the command being sent */
void main(int argc, char **argv) {
int unit,tval,i;
char *dname = "scsi.device";
UBYTE *tbuf;
if( (argc < 2) || (argc > 3) ) {
printf("Usage: %s unit [xxxx.device]\n",argv[0]);
exit(100);
}
unit = atoi( argv[1] );
if ( argc == 3 ) dname = argv[2];
buffer = (UBYTE *) AllocMem( BUFSIZE, MEMF_PUBLIC|MEMF_CLEAR );
if (!buffer) { printf("Couldn't get memory\n"); exit(100); }
Port.mp_Node.ln_Pri = 0; /* setup the ReplyPort */
Port.mp_SigBit = AllocSignal(-1);
Port.mp_SigTask = (struct Task *)FindTask(0);
NewList( &(Port.mp_MsgList) );
SCSIReq.io_Message.mn_ReplyPort = &Port;
if (OpenDevice( dname, unit, &SCSIReq, 0)) {
printf("Couldn't open unit %ld on %s\n",unit,dname);
FreeMem( buffer,BUFSIZE );
exit(100);
}
SCSIReq.io_Length = sizeof(struct SCSICmd);
SCSIReq.io_Data = (APTR)&Cmd;
SCSIReq.io_Command = HD_SCSICMD; /* the command we are sending */
Cmd.scsi_Data = (UWORD *)buffer; /* where we put mode sense data */
Cmd.scsi_Length = 254; /* how much we will accept */
Cmd.scsi_CmdLength = 6; /* length of the command */
Cmd.scsi_Flags = SCSIF_AUTOSENSE|SCSIF_READ;
/* do automatic REQUEST_SENSE */
/* set expected data direction */
Cmd.scsi_SenseData =(UBYTE *)Sense; /* where sense data will go */
Cmd.scsi_SenseLength = 18; /* how much we will accept */
Cmd.scsi_SenseActual = 0; /* how much has been received */
Cmd.scsi_Command=(UBYTE *)ModeSense;/* issuing a MODE_SENSE command */
DoIO( &SCSIReq ); /* send it to the device driver */
if(Cmd.scsi_Status) ShowSenseData(); /* if bad status then show it */
else {
printf("\nBlock descriptor header\n");
printf("=======================\n");
printf("Mode Sense data length = %d\n",(short)buffer[0]);
printf("Block descriptor length = %d\n",(short)buffer[3]);
tbuf = &buffer[4];
printf("Density code = %d\n",(short)tbuf[0]);
tval = (tbuf[1]<<16) + (tbuf[2]<<8) + tbuf[3];
printf("Number of blocks = %ld\n",tval);
tval = (tbuf[5]<<16) + (tbuf[6]<<8) + tbuf[7];
printf("Block size = %ld\n",tval);
tbuf += buffer[3]; /* move to page descriptors */
while( (tbuf - buffer) < buffer[0] ) {
switch ( tbuf[0] & 0x7f ) {
case 1:
printf("\nError Recovery Parameters\n");
printf("=========================\n");
printf("Page length = %d\n",(short)tbuf[1]);
printf("DISABLE CORRECTION = %d\n",(short)tbuf[2]&1);
printf("DISABLE XFER ON ERROR = %d\n",(short)(tbuf[2]>>1)&1);
printf("POST ERROR = %d\n",(short)(tbuf[2]>>2)&1);
printf("ENABLE EARLY CORRECTION = %d\n",(short)(tbuf[2]>>3)&1);
printf("READ CONTINUOUS = %d\n",(short)(tbuf[2]>>4)&1);
printf("TRANSFER BLOCK = %d\n",(short)(tbuf[2]>>5)&1);
printf("AUTO READ REALLOCATION = %d\n",(short)(tbuf[2]>>6)&1);
printf("AUTO WRITE REALLOCATION = %d\n",(short)(tbuf[2]>>7)&1);
printf("Retry count = %d\n",(short)tbuf[3]);
printf("Correction span = %d\n",(short)tbuf[4]);
printf("Head offset count = %d\n",(short)tbuf[5]);
printf("Data strobe offset count= %d\n",(short)tbuf[6]);
printf("Recovery time limit = %d\n",(short)tbuf[7]);
tbuf += tbuf[1]+2;
break;
case 2 :
printf("\nDisconnect/Reconnect Control\n");
printf("============================\n");
printf("Page length = %d\n",(short)tbuf[1]);
printf("Buffer full ratio = %d\n",(short)tbuf[2]);
printf("Buffer empty ratio = %d\n",(short)tbuf[3]);
tval = (tbuf[4]<<8)+tbuf[5];
printf("Bus inactivity limit = %d\n",tval);
tval = (tbuf[6]<<8)+tbuf[7];
printf("Disconnect time limit = %d\n",tval);
tval = (tbuf[8]<<8)+tbuf[9];
printf("Connect time limit = %d\n",tval);
tval = (tbuf[10]<<8)+tbuf[11];
printf("Maximum burst size = %d\n",tval);
printf("Disable disconnection = %d\n",(short)tbuf[12]&1);
tbuf += tbuf[1]+2;
break;
case 3:
printf("\nDevice Format Parameters\n");
printf("========================\n");
printf("Page length = %d\n",(short)tbuf[1]);
tval = (tbuf[2]<<8)+tbuf[3];
printf("Tracks per zone = %d\n",tval);
tval = (tbuf[4]<<8)+tbuf[5];
printf("Alternate sectors/zone = %d\n",tval);
tval = (tbuf[6]<<8)+tbuf[7];
printf("Alternate tracks/zone = %d\n",tval);
tval = (tbuf[8]<<8)+tbuf[9];
printf("Alternate tracks/volume = %d\n",tval);
tval = (tbuf[10]<<8)+tbuf[11];
printf("Sectors per track = %d\n",tval);
tval = (tbuf[12]<<8)+tbuf[13];
printf("Bytes per sector = %d\n",tval);
tval = (tbuf[14]<<8)+tbuf[15];
printf("Interleave = %d\n",tval);
tval = (tbuf[16]<<8)+tbuf[17];
printf("Track skew factor = %d\n",tval);
tval = (tbuf[18]<<8)+tbuf[19];
printf("Cylinder skew factor = %d\n",tval);
tbuf += tbuf[1]+2;
break;
case 4:
printf("\nDrive Geometry Parameters\n");
printf("=========================\n");
printf("Page length = %d\n",(short)tbuf[1]);
tval = (tbuf[2]<<16)+(tbuf[3]<<8)+tbuf[4];
printf("Number of cylinders = %ld\n",tval);
printf("Number of heads = %d\n",(short)tbuf[5]);
tval = (tbuf[6]<<16)+(tbuf[6]<<8)+tbuf[8];
printf("Start write precomp = %ld\n",tval);
tval = (tbuf[9]<<16)+(tbuf[10]<<8)+tbuf[11];
printf("Start reduced write = %ld\n",tval);
tval = (tbuf[12]<<8)+tbuf[13];
printf("Drive step rate = %d\n",tval);
tval = (tbuf[14]<<16)+(tbuf[15]<<8)+tbuf[16];
printf("Landing zone cylinder = %ld\n",tval);
tbuf += tbuf[1]+2;
break;
default:
printf("\nVendor Unique Page Code %2x\n",(short)tbuf[0]);
printf("==========================\n");
for( i=0; i<=tbuf[1]+1; i++ )
printf("%x ",(short)tbuf[i]);
printf("\n");
tbuf += tbuf[1]+2;
}
}
}
CloseDevice( &SCSIReq );
FreeMem( buffer, BUFSIZE );
FreeSignal(Port.mp_SigBit);
}
void ShowSenseData(void)
{
int i;
for(i=0; i<18; i++)
printf("%x ",(int)Sense[i]);
printf("\n");
}