home *** CD-ROM | disk | FTP | other *** search
- /*
- * ASPILIB - communication with Advanced SCSI Programming Interface
- *
- * REFERENCES:
- * Ansi X3T9.2-86 (SCSI-2)
- * ASW1250 - Adaptec Spad-SRB/SCO
- * Adaptec - ASPI DOS Specification
- * Adaptec
- * Literature Departement - MS/40
- * 691 South Milpitas Blvd.
- * Milpitas, CA 95035
- *
- * NOTES ON COMMAND LINKING:
- * In order to use Command-Linking (might be supported by some targets)
- * a chain of SRBs has to be build via array 'lpSrbLink'.
- * Flag SRBF_LINKED has to be set to one in all requests (except the last
- * one).
- * Same applies to the Link bit in the corresponding CDBs.
- *
- * PS (from Adaptec!): It is strongly recommended that you do not use SCSI
- * linking (unless you have no other choice). (reason: too less targets as
- * well as host adapters do support these features!)
- *
- * COMPILING:
- * cl -c -Gy -O1 aspilib.c
- *
- * LAST CHANGE:
- * 17.10.93 - first version, OK
- * 08.11.93 - supplement for POST support, OK
- * 22.12.93 - redesign and rewrite for SRB-oriented funktions, OK
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "uti.h"
- #include "aspidef.h"
-
- #pragma warning (disable:4704) // inline assembly is valid!
-
-
- #if 0
-
- /*
- * SCSIREQ - SCSI request descriptor
- *
- * ELEMENTS:
- * datasent: Amount of data bytes actually transferred via SCSI bus.
- * There ought to be operating systems, not being able to determine this
- * value.
- * In this case 'datasent' is identical to 'ScsiRequest''s
- * parameter 'cbData'.
- * sensesent: amount of sense data received from target in 'sensebuf'.
- * sensebuf: buffer to receive target send SENSE data.
- */
- typedef struct SCSIREQ {
- long datasent;
- long sensesent;
- char sensebuf [CBSENSEBUF];
-
- /* internal */
- u_char target_sts;
- u_char driver_sts;
- int fd;
- long req;
- } SCSIREQ;
-
- SCSIREQ *ScsiOpen (char *name);
- int ScsiClose (SCSIREQ *scsireq);
- int ScsiRequest (SCSIREQ *scsireq, int direction, u_char *pCmd, int cbCmd,
- u_char *pData, int cbData);
- int ScsiTestUnitReady (SCSIREQ *scsireq);
- int ScsiInquire (SCSIREQ *scsireq, char *pBuf, int cbBuf);
- #endif
-
-
- typedef struct ASPIERROR {
- int errorCode;
- char *szError;
- } ASPIERROR;
-
- static ASPIERROR aspiError [] = {
- {ASPIE_SUCCESS, "Ok"},
- {ASPIE_PENDING, "Pending SCSI request"},
- {ASPIE_FATAL, "Undefined ASPI error"},
- {ASPIE_INVDEVICEID, "SCSI device not installed"},
- {ASPIE_INVSCSIREQ, "Invalid SCSI request"},
- {ASPIE_INVADAPTERID, "Invalid host adapter number"},
- {ASPIE_HOSTABORT, "ASPI request aborted by host"},
- {ASPIE_SELTIMEOUT, "Selection timeout"},
- {ASPIE_DATAOVERRUN, "Data over-run/under-run"},
- {ASPIE_BUSFREE, "Unexpected bus free"},
- {ASPIE_PHASEERR, "Target bus phase sequence failure"},
- {ASPIE_TARGETBUSY, "Specified target is busy"},
- {ASPIE_RESERVATION, "Reservation conflict"},
- {ASPIE_UNITNOTREADY, "Unit not ready"},
- {ASPIE_MEDIUM, "Medium error"},
- {ASPIE_HARDWARE, "Non-recoverable hardware failure"},
- {ASPIE_ILLEGALREQ, "Illegal request"},
- {ASPIE_UNITATTENTION, "Unit attention"},
- {ASPIE_DATAPROTECT, "Medium is write protected"},
- {ASPIE_BLANKCHECK, "Encountered non blank data"},
- {ASPIE_TARGETABORT, "Command aborted by target"},
- {ASPIE_VOLOVERFLOW, "Volume overflow"},
- {ASPIE_IOERROR, "Unknown I/O error"},
- {ASPIE_ENDOFMEDIUM, "End of medium detected"},
- {1, "<<Error>>"}
- };
-
-
- char *AspiGetErrorText (int errorCode)
- /*
- * This function returns an error text corresponding to error code of
- * ASPI functions.
- *
- * PARAMETERS:
- * errorCode: error code from one of the 'Aspi...' functions, which return
- * ASPIE_...
- *
- * RETURN:
- * pointer to a static error text.
- */
- {
- ASPIERROR *pAspiError = aspiError;
-
- while (pAspiError -> errorCode < 1 && pAspiError -> errorCode != errorCode)
- pAspiError++;
- return pAspiError -> szError;
- }
-
-
- BOOL AspiInit (VOID)
- /*
- * This function initialises internal structures of the ASPI library and
- * opens the interface to the resident SCSI manager.
- *
- * RETURN:
- * FALSE: ASPI interface has not been installed,
- * TRUE: ASPI interface has been opened correctly.
- */
- {
- static char NEAR *szScsiMgr = "SCSIMGR$";
-
- #ifndef TURBOC
- _asm {
- mov dx,szScsiMgr
- mov ax,3D00h
- int 21h
- jc failed
- mov bx,ax
-
- mov cx,4
- lea dx,word ptr fnAspi
- mov ax,4402h
- int 21h
-
- mov ah,3Eh
- int 21h
- }
- #else
- asm mov dx,szScsiMgr
- asm mov ax,3D00h
- asm int 21h
- asm jc failed
- asm mov bx,ax
-
- asm mov cx,4
- asm lea dx,word ptr fnAspi
- asm mov ax,4402h
- asm int 21h
-
- asm mov ah,3Eh
- asm int 21h
- #endif
- failed:
-
- return fnAspi != NULL;
- }
-
-
- int AspiPostRequest (SRB *srb)
- {
- fnAspi (srb);
- return srb -> bStatus;
- }
-
-
- int AspiGetError (SRB *srb)
- /*
- * This function determines the error state from a SRB.
- *
- * PARAMETERS:
- * srb: pointer to the SRB handled by 'AspiRequest' or 'AspiRequestWait.'
- *
- * RETURN:
- * On successful operation on 'srb' ASPIE_SUCCESS, values smaller zero
- * indicate an ASPIE_... error.
- *
- * BUGS:
- * the calling function is in charge to ensure the value of 'bStatus'
- * in SRB is no more SRBS_PENDING.
- */
- {
- BYTE *sense;
- const SRB_IO *srbIo = (SRB_IO *)srb;
-
- switch (srb -> bStatus) {
- case SRBS_PENDING: return ASPIE_PENDING;
- case SRBS_COMPLETE: return ASPIE_SUCCESS;
- case SRBS_ABORTED: return ASPIE_HOSTABORT;
-
- case SRBS_ERROR:
- if (srb -> bCmd != SRBC_EXECIO) return ASPIE_FATAL;
-
- /* SCSI-IO-Error: more data about error? */
- switch (srbIo -> bAdapterStatus) {
-
- case 0x00: /* not an error by adapter, anything from target? */
- switch (srbIo -> bTargetStatus) {
-
- case 0x02: /* target said Check Sense */
- sense = srbIo -> cdb.raw + srbIo -> cCdb;
- switch (sense [2] & 0x0F) {
- case 0x00:
- if (sense [2] & 0x40) return ASPIE_ENDOFMEDIUM;
- break;
- case 0x01: return ASPIE_SUCCESS; /* recovered error */
- case 0x02: return ASPIE_UNITNOTREADY;
- case 0x03: return ASPIE_MEDIUM;
- case 0x04: return ASPIE_HARDWARE;
- case 0x05: return ASPIE_ILLEGALREQ;
- case 0x06: return ASPIE_UNITATTENTION;
- case 0x07: return ASPIE_DATAPROTECT;
- case 0x08: return ASPIE_BLANKCHECK;
- case 0x0B: return ASPIE_TARGETABORT;
- case 0x0D: return ASPIE_VOLOVERFLOW;
- }
- break;
-
- case 0x08: return ASPIE_TARGETBUSY;
- case 0x18: return ASPIE_RESERVATION;
- }
- break;
-
- case 0x11: return ASPIE_SELTIMEOUT;
- case 0x12: return ASPIE_DATAOVERRUN;
- case 0x13: return ASPIE_BUSFREE;
- case 0x14: return ASPIE_PHASEERR;
- }
- return ASPIE_IOERROR;
-
- case SRBS_INVSCSIREQ: return ASPIE_INVSCSIREQ;
- case SRBS_INVADAPTERID: return ASPIE_INVADAPTERID;
- case SRBS_INVDEVICEID: return ASPIE_INVDEVICEID;
- }
-
- return ASPIE_FATAL;
- }
-
-
- int AspiRequestWait (SRB *srb)
- {
- int cnt = 10;
-
- fnAspi (srb);
- while (cnt--) while (not srb -> bStatus);
-
- return AspiGetError (srb);
- }
-
-
- int AspiAbortRequest (SRB *srb)
- /*
- * this function aborts a command, which was initiated by 'AspiRequest'.
- *
- * PARAMETERS:
- * srb: pointer to command to be aborted.
- *
- * RETURN:
- * On success: ASPIE_SUCCESS, values smaller zero indicate an error.
- *
- * BUGS:
- * We don't know for sure, whether the command has been aborted.
- * command state might be SRBS_COMPLETE already when calling
- * 'AspiAbortRequest'.
- *
- * Function 'AspiAbortRequest' may not called from inside a POST-Routine.
- */
- {
- SRB_ABORT srbAbort;
-
- memzero (srbAbort);
-
- srbAbort.srb.bCmd = SRBC_ABORTSRB;
- srbAbort.srb.bAdapterId = srb -> bAdapterId;
- srbAbort.lpSrbToAbort = srb;
-
- return AspiRequestWait (&srbAbort.srb);
- }
-
-
- int AspiHostAdapterInquiry (int adapterId, HA_INQUIRY *pInquiry)
- /*
- * this function returns informations on an installed host adapter.
- *
- * PARAMETERS:
- * adapterId: number of adapter to query. The first adapter has number zero.
- * pInquiry: pointer on adapter information structure to fill.
- *
- * RETURN:
- * on succes: ASPIE_SUCCESS, values smaller zero indicate errors.
- *
- * BUGS:
- * 'adapterId' has to have valid adapter numbers.
- * Invalid values in 'adapterId' do not return SRBS_COMPLETE in
- * 'srb'.'bStatus'
- */
- {
- int i;
- int err;
- SRB_INQUIRY srbInquiry;
-
- memzero (srbInquiry);
-
- srbInquiry.srb.bCmd = SRBC_INQUIRY;
- srbInquiry.srb.bAdapterId = (BYTE)adapterId;
-
- err = AspiRequestWait (&srbInquiry.srb);
- if (err) return err;
-
- for (i=0; i<16; i++) {
- pInquiry -> szManager [i] = srbInquiry.achManager [i];
- pInquiry -> szAdapter [i] = srbInquiry.achAdapter [i];
- }
-
- pInquiry -> szManager [16] = '\0';
- pInquiry -> szAdapter [16] = '\0';
- pInquiry -> nAdapters = srbInquiry.nAdapters;
- pInquiry -> adapterTargetId = srbInquiry.adapterTargetId;
-
- return ASPIE_SUCCESS;
- }
-
-
- int AspiGetDeviceType (int adapterId, int targetId, int lun)
- /*
- * This function returns the device type of a connected SCSI device.
- *
- * PARAMETERS:
- * adapterId: Number of adapter.
- * targetId: SCSI ID of device to inquire.
- * lun: Logical Unit Number of device to inquire.
- *
- * RETURN:
- * If greater or equal zero: the SCSI Device Type Code (DTC_...) of
- * target 'targetId'. Values smaller zero indicate an error.
- *
- * BUGS:
- * This function returns correct information only about devices, having
- * been connected at boot time. Devices turned on after booting
- * are not supported and return an error code smaller zero.
- */
- {
- int err;
- SRB_GETDEVTYPE srbGetDevType;
-
- memzero (srbGetDevType);
-
- srbGetDevType.srb.bCmd = SRBC_GETDEVTYPE;
- srbGetDevType.srb.bAdapterId = (BYTE)adapterId;
- srbGetDevType.bTargetId = (BYTE)targetId;
- srbGetDevType.bLun = (BYTE)lun;
-
- err = AspiRequestWait (&srbGetDevType.srb);
- if (err) return err;
-
- return srbGetDevType.bDeviceTypeCode;
- }
-
-
- int AspiResetDevice (int adapterId, int targetId, int lun)
- /*
- * This function resets an scsi device.
- *
- * PARAMETERS:
- * adapterId, targetId, lun: address of device to reset.
- *
- * RETURN:
- * On success:ASPIE_SUCCESS, Values smaller zero indicate an error.
- */
- {
- SRB_RESET srbReset;
-
- memzero (srbReset);
- srbReset.srb.bCmd = SRBC_RESETDEVICE;
- srbReset.srb.bAdapterId = (BYTE)adapterId;
- srbReset.bTargetId = (BYTE)targetId;
- srbReset.bLun = (BYTE)lun;
-
- return AspiRequestWait (&srbReset.srb);
- }
-
-
- int AspiGetDiskDriveInfo (int adapterId, int targetId, int lun,
- HA_DRIVEINFO *pDriveInfo)
- /*
- * This function returns informations about disk for usage by DOS and BIOS.
- *
- * PARAMETERS:
- * adapterId, targetId, lun: address of device to query.
- * pDriveInfo: pointer to result of query structure.
- *
- * RETURN:
- * On success:ASPIE_SUCCESS, Values smaller zero indicate an error.
- */
- {
- SRB_GETDRIVEINFO srbGetDriveInfo;
-
- memzero (srbGetDriveInfo);
-
- srbGetDriveInfo.srb.bCmd = SRBC_GETDRIVEINFO;
- srbGetDriveInfo.srb.bAdapterId = (BYTE)adapterId;
- srbGetDriveInfo.bTargetId = (BYTE)targetId;
- srbGetDriveInfo.bLun = (BYTE)lun;
-
- *pDriveInfo = srbGetDriveInfo.driveInfo;
-
- return AspiRequestWait (&srbGetDriveInfo.srb);
- }
-
-
- int ScsiTestUnitReady (int adapterId, int targetId, int lun)
- /*
- * This function checks the accessability of an scsi device.
- *
- * PARAMETERS:
- * adapterId, targetId, lun: address of device to check.
- *
- * RETURN:
- * If device is ready: ASPIE_SUCCESS, Values smaller zero indicate
- * an error.
- */
- {
- SRB_IO srbIo;
-
- memzero (srbIo);
-
- srbIo.srb.bCmd = SRBC_EXECIO;
- srbIo.srb.bAdapterId = (BYTE)adapterId;
- srbIo.srb.bFlags = SRBF_NOXFER;
- srbIo.bTargetId = (BYTE)targetId;
- srbIo.bLun = (BYTE)lun;
- srbIo.lpData = NULL;
- srbIo.cbData = 0;
- srbIo.cbSense = 14;
- srbIo.cCdb = 6;
-
- return AspiRequestWait (&srbIo.srb);
- }
-
-
- int ScsiInquiry (int adapterId, int targetId, int lun, SCSI_INQUIRY *pInquiry)
- /*
- * This function requests SCSI Inquire data from an scsi device.
- *
- * PARAMETERS:
- * adapterId, targetId, lun: address of device to inquire.
- * pInquiry: pointer to structure to fill in inquire data.
- *
- * RETURN:
- * On success: ASPIE_SUCCESS, Values smaller zero indicate an error.
- */
- {
- SRB_IO srbIo;
-
- memzero (srbIo);
-
- srbIo.srb.bCmd = SRBC_EXECIO;
- srbIo.srb.bAdapterId = (BYTE)adapterId;
- srbIo.srb.bFlags = SRBF_READ;
- srbIo.bTargetId = (BYTE)targetId;
- srbIo.bLun = (BYTE)lun;
- srbIo.lpData = pInquiry;
- srbIo.cbData = sizeof (SCSI_INQUIRY);
- srbIo.cbSense = 14;
- srbIo.cCdb = 6;
- srbIo.cdb.inquiry.bCmd = 0x12;
- srbIo.cdb.inquiry.bLun = lun;
- srbIo.cdb.inquiry.bLen = sizeof (SCSI_INQUIRY);
-
- return AspiRequestWait (&srbIo.srb);
- }
-
-
- int ScsiRead (int adapterId, int targetId, int lun, VOID *pBuffer,
- int firstBlock, int nBlocks)
- {
- SRB_IO srbIo;
-
- srbIo.srb.bCmd = SRBC_EXECIO;
- srbIo.srb.bAdapterId = adapterId;
- srbIo.srb.bFlags = SRBF_READ;
- srbIo.bTargetId = targetId;
- srbIo.bLun = lun;
- srbIo.cbData = nBlocks * 512;
- srbIo.cbSense = 14;
- srbIo.lpData = pBuffer;
- srbIo.cCdb = 6;
- srbIo.cdb.cdb6.bCmd = 0x08;
- srbIo.cdb.cdb6.bLun = lun;
- srbIo.cdb.cdb6.b2 = (BYTE)(firstBlock >> 8);
- srbIo.cdb.cdb6.b3 = (BYTE)firstBlock;
- srbIo.cdb.cdb6.b4 = (BYTE)nBlocks;
- srbIo.cdb.cdb6.b5 = 0;
-
- return AspiRequestWait (&srbIo.srb);
- }
-
-
- int ScsiWrite (int adapterId, int targetId, int lun, VOID *pBuffer,
- int firstBlock, int nBlocks)
- {
- SRB_IO srbIo;
-
- srbIo.srb.bCmd = SRBC_EXECIO;
- srbIo.srb.bAdapterId = adapterId;
- srbIo.srb.bFlags = SRBF_WRITE;
- srbIo.bTargetId = targetId;
- srbIo.bLun = lun;
- srbIo.cbData = nBlocks * 512;
- srbIo.cbSense = 14;
- srbIo.lpData = pBuffer;
- srbIo.cCdb = 6;
- srbIo.cdb.cdb6.bCmd = 0x0A;
- srbIo.cdb.cdb6.bLun = lun;
- srbIo.cdb.cdb6.b2 = (BYTE)(firstBlock >> 8);
- srbIo.cdb.cdb6.b3 = (BYTE)firstBlock;
- srbIo.cdb.cdb6.b4 = (BYTE)nBlocks;
- srbIo.cdb.cdb6.b5 = 0;
-
- return AspiRequestWait (&srbIo.srb);
- }
-
- #ifdef TEST_READ
-
- VOID StopUnit (int targetId)
- {
- int err;
- SRB_IO srbIo;
-
- memzero (srbIo);
-
- srbIo.srb.bCmd = SRBC_EXECIO;
- srbIo.srb.bAdapterId = 0;
- srbIo.srb.bFlags = SRBF_READ;
- srbIo.bTargetId = (BYTE)targetId;
- srbIo.bLun = 0;
- srbIo.lpData = NULL;
- srbIo.cbData = 0;
- srbIo.cbSense = 14;
- srbIo.cCdb = 6;
- srbIo.cdb.ssunit.bCmd = 0x1B;
- srbIo.cdb.ssunit.fImmed = 0;
- srbIo.cdb.ssunit.fStart = 0;
-
- err = AspiRequestWait (&srbIo.srb);
- printf ("start stop = %s\n", AspiGetErrorText (err));
- }
-
-
- BYTE buffer [1024];
-
- int main (int argc, char *argv [])
- {
- int i;
- int err;
-
- if (not AspiInit ()) {
- puts ("ASPI interface not installed.");
- return 1;
- }
-
- memset (buffer, 0xAA, sizeof (buffer));
- err = AspiResetDevice (0, 2, 0);
- puts (AspiGetErrorText (err));
-
- getch ();
- err = ScsiRead (0, 2, 0, buffer, 1, 1);
- if (err) {
- puts (AspiGetErrorText (err));
- }
-
- for (i=0; i<128; i+=16) {
- int j;
-
- for (j=0; j<16; j++)
- printf (" %.2X", buffer [i+j]);
- printf ("\n");
- }
-
- StopUnit (2);
-
- return 0;
- }
-
-
- #endif
-
- #ifdef TEST_DUMP
-
- int cxLabel = 30;
-
- VOID Label (char *szLabel, char *szFormat, ...)
- {
- int x = -4;
-
- if (szLabel) {
- x = strlen (szLabel);
- if (x > cxLabel) szLabel [cxLabel] = '\0';
- fputs (szLabel, stdout);
- }
-
- if (szLabel) {
- putchar (' ');
- while (x++ < cxLabel) putchar ('.');
- fputs (" : ", stdout);
- } else {
- while (x++ < cxLabel) putchar (' ');
- }
-
- if (szFormat) {
- vprintf (szFormat, (va_list)(&szFormat+1));
- putchar ('\n');
- }
- }
-
-
- typedef struct DEVICEINFO {
- int adapterId;
- int targetId;
- int lun;
- SCSI_INQUIRY scsiInquiry;
- } DEVICEINFO;
-
- #define CDEVICEINFO 16
- DEVICEINFO deviceInfo [CDEVICEINFO];
- int nDeviceInfos = 0;
-
-
- VOID GetDeviceInfo (int nAdapters)
- {
- int err;
- int adapterId;
- int targetId;
- int lun;
- DEVICEINFO *pDeviceInfo = deviceInfo;
-
- printf ("\nList of SCSI devices:\n");
- printf (" Id Vendor Product name Revision\n");
-
- for (adapterId=0; adapterId<nAdapters; adapterId++) {
- for (targetId=0; targetId<8; targetId++) {
- for (lun=0; lun<8; lun++) {
- err = AspiGetDeviceType (adapterId, targetId, lun);
- if (err == ASPIE_INVDEVICEID) continue;
-
- err = ScsiInquiry (adapterId, targetId, lun,
- &pDeviceInfo -> scsiInquiry);
- printf (" %d:%d:%d ", adapterId, targetId, lun);
- if (err < 0) {
- puts (AspiGetErrorText (err));
- continue;
- }
-
- pDeviceInfo -> adapterId = adapterId;
- pDeviceInfo -> targetId = targetId;
- pDeviceInfo -> lun = lun;
- printf ("%.8s %.16s %.4s\n", pDeviceInfo -> scsiInquiry.achVendor,
- pDeviceInfo -> scsiInquiry.achProduct,
- pDeviceInfo -> scsiInquiry.achRevision);
-
- pDeviceInfo++;
- nDeviceInfos++;
- if (nDeviceInfos == CDEVICEINFO) return;
- }
- }
- }
- }
-
-
- VOID PrintDeviceTypeCode (int deviceTypeCode)
- {
- static char *szDeviceTypeCode [] = {
- "Disk", "Tape", "Printer", "CPU", "Worm", "CD-ROM", "Scanner",
- "Optical", "Jukebox", "Comm", "Prepress", "Prepress", "Unknown"};
-
- if (deviceTypeCode > 12)
- deviceTypeCode = 12;
- printf ("%-8s ", szDeviceTypeCode [deviceTypeCode]);
- }
-
-
- VOID PrintYesNo (BOOL fYes)
- {
- printf ("%-8s ", fYes ? "Yes" : "No");
- }
-
-
- int main (VOID)
- {
- int i;
- int err;
- HA_INQUIRY haInquiry;
-
- if (not AspiInit ()) {
- puts ("ASPI interface not installed.");
- return 1;
- }
-
- err = AspiHostAdapterInquiry (0, &haInquiry);
- if (err) {
- printf ("adapter0: %s\n", AspiGetErrorText (err));
- }
-
- printf ("Host adapter information:\n");
- Label (" Number of adapters", "%d", haInquiry.nAdapters);
- Label (" Type of adapter 0", "%s", haInquiry.szAdapter);
- Label (" SCSI manager 0", "%s", haInquiry.szManager);
- Label (" Adapter 0 target-id", "%d", haInquiry.adapterTargetId);
-
- GetDeviceInfo (haInquiry.nAdapters);
- cxLabel = 22; /* reicht für 6 Geräte */
-
- printf ("\nDevice information:");
- Label ("\n SCSI-Id", NULL);
- for (i=0; i<nDeviceInfos; i++)
- printf ("%d:%d:%d ", deviceInfo [i].adapterId,
- deviceInfo [i].bTargetId, deviceInfo [i].bLun);
-
- Label ("\n Manufacturer", NULL);
- for (i=0; i<nDeviceInfos; i++)
- printf ("%.8s ", deviceInfo [i].scsiInquiry.achVendor);
-
- Label ("\n Device type", NULL);
- for (i=0; i<nDeviceInfos; i++)
- PrintDeviceTypeCode (deviceInfo [i].scsiInquiry.deviceTypeCode);
-
- Label ("\n Removable medium", NULL);
- for (i=0; i<nDeviceInfos; i++)
- PrintYesNo (deviceInfo [i].scsiInquiry.fRemovableMedium);
-
- Label ("\n SCSI version", NULL);
- for (i=0; i<nDeviceInfos; i++)
- printf ("SCSI-%d ", deviceInfo [i].scsiInquiry.scsiVersion);
-
- Label ("\n Command queueing", NULL);
- for (i=0; i<nDeviceInfos; i++)
- PrintYesNo (deviceInfo [i].scsiInquiry.fCmdQueueing);
-
- Label ("\n Linked commands", NULL);
- for (i=0; i<nDeviceInfos; i++)
- PrintYesNo (deviceInfo [i].scsiInquiry.fLinkedCommands);
-
- Label ("\n Sync transfer", NULL);
- for (i=0; i<nDeviceInfos; i++)
- PrintYesNo (deviceInfo [i].scsiInquiry.fSynchronousTransfer);
-
- printf ("\n");
-
- return 0;
- }
-
- #endif
-
-
- #ifdef TEST_BENCH
-
- #include <dos.h>
-
- static volatile DWORD FAR *sysTime = (DWORD FAR *)0x0040006CL;
- DWORD _startTime;
- BYTE buffer [64L*1024];
-
-
- VOID ResetTimer (VOID)
- {
- _disable ();
- _startTime = *sysTime;
- _enable ();
- while (_startTime == *sysTime);
- _startTime++;
- }
-
-
- DWORD GetTimer (VOID)
- /*
- * Returns passed time since last call of 'ResetTimer' in milli seconds.
- */
- {
- DWORD stopTime;
-
- _disable ();
- stopTime = *sysTime;
- _enable ();
- return (stopTime - _startTime) * 28125 / 512;
- }
-
-
- /* size of read buffer in kbytes */
- #define TEST_SIZE 64
-
- VOID ScsiReadBlocks (int adapterId, int targetId, int kByteStart, int kBytes)
- {
- int block;
-
- block = kByteStart * 2;
- while (kBytes > TEST_SIZE) {
- ScsiRead (adapterId, targetId, /*lun*/ 0, buffer, block, TEST_SIZE*2);
- block += TEST_SIZE*2;
- kBytes -= TEST_SIZE;
- }
- if (kBytes > 0)
- ScsiRead (adapterId, targetId, /*lun*/ 0, buffer, block, kBytes*2);
- }
-
-
- int main (int argc, char *argv [])
- {
- int i;
- int err;
- DWORD time;
- int deviceType;
- int adapterId = 0;
- int targetId = 0;
- SCSI_INQUIRY scsiInquiry;
-
- if (not AspiInit ()) {
- puts ("ASPI interface not installed.");
- return 1;
- }
-
- if (argc == 2) {
- targetId = argv [1][0] - '0';
- if (targetId < 0 || targetId > 7) targetId = 0;
- }
-
- deviceType = AspiGetDeviceType (adapterId, targetId, /*lun*/ 0);
- if (deviceType != DTC_DISK && deviceType != DTC_CDROM) {
- printf ("Target %d:%d:0 is not a disk drive.\n", adapterId, targetId);
- return 1;
- }
- err = ScsiInquiry (adapterId, targetId, /*lun*/0, &scsiInquiry);
- if (err) {
- puts (AspiGetErrorText (err));
- return 1;
- }
- printf ("Device %d:%d:%d ........... : %.8s %.16s %.4s\n",
- adapterId, targetId, /*lun*/0, scsiInquiry.achVendor,
- scsiInquiry.achProduct, scsiInquiry.achRevision);
-
- err = ScsiTestUnitReady (adapterId, targetId, /*lun*/0);
- if (err) {
- puts (AspiGetErrorText (err));
- return 1;
- }
-
- /* flush disk cache */
- ScsiReadBlocks (adapterId, targetId, 0, 1024);
-
- ResetTimer ();
- ScsiReadBlocks (adapterId, targetId, 1024, 10240);
- time = GetTimer () + 1;
- printf ("Time to read 10MB ...... : %ld ms\n", time);
- printf ("Real performance ....... : %ld KB/s\n", 10240L * 1000 / time);
-
- for (i=1; i<=4; i++) {
- int j;
-
- ScsiReadBlocks (adapterId, targetId, 0, i*16);
- ScsiReadBlocks (adapterId, targetId, 0, i*16);
- ResetTimer ();
- for (j=0; j<99; j++)
- ScsiReadBlocks (adapterId, targetId, 0, i*16);
- time = GetTimer ();
- printf ("Read from cache %dKB ... : ", i*16);
- if (time == 0) {
- printf ("oops\n");
- } else {
- printf ("%ld KB/s\n", 99 * i * 16L * 1000 / time);
- }
- }
-
- return 0;
- }
-
- #endif
-
-
- #ifdef TEST_PATCHSQ
-
- typedef struct BOOTSECTOR {
- BYTE bsJump [3];
- char bsOemName [8];
- WORD wBytesPerSector;
- BYTE bSectorsPerCluster;
- WORD wReservedSectors;
- BYTE nFats;
- WORD nRootDirEntries;
- WORD wTotalSectors;
- BYTE bMediaDescriptor;
- WORD wSectorsPerFAT;
- WORD wSectorsPerTrack;
- WORD nHeads;
- DWORD dwHiddenSectors;
- /* extended ... */
- DWORD dwTotalSectors;
- WORD wPhysicalDriveNumber;
- BYTE bExtBoot29h;
- DWORD dwVolumeID;
- char strVolumeLable [11];
- char strFileSysType [7];
- char _reserved [451];
- } BOOTSECTOR;
-
- BOOTSECTOR bootSector;
-
-
- int main (int argc, char *argv [])
- {
- int i;
- int targetId;
- int err;
- SCSI_INQUIRY scsiInquiry;
-
- if (not AspiInit ()) {
- puts ("ASPI interface not installed.");
- return 1;
- }
-
- for (targetId=0; targetId<8; targetId++) {
- if (AspiGetDeviceType (0, targetId, 0) != DTC_DISK) continue;
- err = ScsiInquiry (0, targetId, 0, &scsiInquiry);
- if (err) {
- puts (AspiGetErrorText (err));
- continue;
- }
- if (strncmp (scsiInquiry.achVendor, "SyQuest ", 8) == 0) break;
- }
- if (targetId == 8) {
- puts ("No SyQuest drive connected to adapter0.");
- return 1;
- }
-
- fputs ("target", stdout);
- fputc (targetId + '0', stdout);
- puts (": reading boot sector...");
- memset (&bootSector, 0xFF, sizeof (bootSector));
- err = ScsiRead (0, targetId, 0, &bootSector, 17, 1);
- if (err) {
- puts (AspiGetErrorText (err));
- return 2;
- }
-
- if (bootSector.wSectorsPerTrack == 32 &&
- bootSector.nHeads == 64 &&
- bootSector.dwHiddenSectors == 32) {
- puts ("This cartridge is already patched.");
- return 0;
- }
-
- if (bootSector.wSectorsPerTrack != 17 ||
- bootSector.nHeads != 8 ||
- bootSector.dwHiddenSectors != 17) {
- puts ("Valid boot sector not found.");
- return 3;
- }
-
- fputs ("Boot sector written by: ", stdout);
- for (i=0; i<8; i++) fputc (bootSector.bsOemName [i], stdout);
- fputc ('\n', stdout);
-
- puts ("Cartridge needs patching. Type 'y' to patch cartridge:");
- i = fgetc (stdin);
- if (i == 'y' || i == 'Y' || i == 'j' || i == 'J') {
- bootSector.wSectorsPerTrack = 32;
- bootSector.nHeads = 64;
- bootSector.dwHiddenSectors = 32;
- err = ScsiWrite (0, targetId, 0, &bootSector, 17, 1);
- if (err) {
- puts (AspiGetErrorText (err));
- return 4;
- }
- puts ("Cartridge successfully patched.");
- } else {
- puts ("Cartridge not modified.");
- }
-
- return 0;
- }
-
- #endif
-