Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Src/SCSIAsyncSample.h
/* SCSIAsyncSample.h */ |
/* |
* SCSIAsyncSample.h |
* Copyright © 1992-93 Apple Computer Inc. All Rights Reserved. |
*/ |
#define kApplicationCreator '????' |
#define MBAR_MenuBar 1000 |
#define MENU_Apple 1 |
#define MENU_File 128 |
#define MENU_Edit 129 |
#define STRS_SenseBase 1000 |
#define DLOG_About 128 |
#define DLOG_Query 129 |
#define ALRT_NoNewSCSI 9000 |
#define ALRT_FatalError 9001 |
#define ALRT_NoMemory 9002 |
#define ALRT_NonFatalError 9003 |
#define ACUR_Animator 128 |
#define kMinWindowWidth 200 |
#define kMinWindowHeight 300 |
#define kLogLines 512 |
#define kRequestMemory 100 |
#ifndef REZ |
#ifndef THINK_C /* MPW includes */ |
#include <Errors.h> |
#include <Script.h> |
#include <Types.h> |
#include <Resources.h> |
#include <QuickDraw.h> |
#include <Fonts.h> |
#include <Events.h> |
#include <Windows.h> |
#include <ToolUtils.h> |
#include <Memory.h> |
#include <Menus.h> |
#include <Lists.h> |
#include <Printing.h> |
#include <Dialogs.h> |
#include <Packages.h> |
#include <Controls.h> |
#endif |
/* |
* These definitions are only for the code files. |
*/ |
#ifndef TRUE |
#define TRUE 1 |
#define FALSE 0 |
#endif |
#ifndef EXTERN |
#define EXTERN extern |
#endif |
#include "SCSIDefinitions.h" |
#include "LogManager.h" |
#include "MicrosecondTrap.h" |
/* |
* Include the O.S. files in a specific order to make sure that we have |
* a definition for the _SCSIAtomic trap. |
*/ |
#include <Traps.h> |
#ifndef _SCSIAtomic |
#define _SCSIAtomic 0xA089 |
#endif |
/* |
* Note that this uses a later version of <Scsi.h> than is available in |
* the published headers. |
*/ |
#include "Scsi.h" |
#define kScrollBarWidth 16 |
#define kScrollBarOffset (kScrollBarWidth - 1) |
/* |
* Items in the Apple Menu |
*/ |
enum { |
kAppleAbout = 1 |
}; |
/* |
* Items in the File Menu |
*/ |
enum { |
kFileCreateLogFile = 1, |
kFileCloseLogFile, |
kFileUnused1, |
kFilePageSetup, |
kFilePrint, |
kFileUnused2, |
kFileDebug, |
kFileUnused3, |
kFileQuit |
}; |
enum EditMenu { |
kEditUndo = 1, |
kEditUnused, |
kEditCut, |
kEditCopy, |
kEditPaste, |
kEditClear |
}; |
/* |
* Items in the Query Dialog |
*/ |
enum { |
kQueryTest = 1, |
kQueryFinished, |
kQueryHostBus, |
kQueryTargetID, |
kQueryTotalRequests, |
kQueryBlocksPerTransfer, |
kQueryTimeout, |
kQueryEnableAsync, |
kQueryEnableDisconnect, |
kQueryRandomSeek, |
kQueryThreadNumber, |
kQueryVendorID, |
kQueryProduct, |
kQueryLogicalBlockLength, |
kQueryBlocksOnDevice |
}; |
typedef struct VMHoldRecord { |
void *ptr; |
unsigned long size; |
} VMHoldRecord, *VMHoldPtr; |
enum { |
kVMFunction = 0, |
kVMStack, |
kVMParam, |
kVMBuffer, |
kVMSense, |
kVMSize /* Must be last */ |
}; |
typedef struct RequestMemory { |
unsigned long blockNumber; |
UnsignedWide startTime; |
UnsignedWide endTime; |
} RequestMemory, *RequestMemoryPtr; |
/* |
* This is the information we need for each execution thread. They are |
* created by the query dialog loop. These records are stored in |
* permanent physical memory (HoldMemory) |
*/ |
struct InfoRecord { |
struct ScsiCmdBlock *link; /* Queue link pointer */ |
short qType; /* Unused for OSQueue */ |
SCSIExecIOPB *pb; /* For SCSI Mgr Request */ |
unsigned long pbSize; /* Sizeof param block */ |
Ptr bufferPtr; /* -> transfer buffer */ |
unsigned long bufferLength; /* == allocated length */ |
unsigned short threadIndex; /* Which thread is it */ |
Boolean deviceActive; /* TRUE when busy */ |
Boolean testCompleted; /* TRUE when finished */ |
unsigned long completionTimeout; /* I/O Timeout */ |
unsigned long transferQuantum; /* Transfer quantum */ |
unsigned long randomSeed; /* Random number for seek test */ |
/* Data from the dialog */ |
DeviceIdent deviceIdent; /* Bus/Target/LUN */ |
unsigned long transferSizeBlocks; /* Blocks to transfer */ |
unsigned long totalTransfers; /* Transfers to perform */ |
unsigned long transfersAttempted; /* Calls to SCSIAction */ |
Boolean enableAsync; /* Asynch checked? */ |
Boolean enableDisconnect; /* Disconnect checked? */ |
Boolean enableRandomSeek; /* Random seek test */ |
/* Data resulting from Read Capacity */ |
unsigned long totalLogicalBlocks; /* Blocks on device */ |
unsigned long logicalBlockLength; /* Logical block size */ |
/* Data resulting from Device Inquiry */ |
unsigned char vendor[9]; /* Vendor name (pascal) */ |
unsigned char product[17]; /* Product ID (pascal) */ |
/* Data changed by/for each transfer request */ |
OSErr finalStatus; /* First detected error */ |
SCSI_Command command; /* == Current command */ |
unsigned long blockNumber; /* Read from this block */ |
unsigned long blockCount; /* Blocks to transfer */ |
unsigned long byteCount; /* Bytes to transfer */ |
unsigned long nextBlockNumber; /* Block to start next time */ |
unsigned long transfersCompleted; /* I/O Completion count */ |
unsigned long asynchRequests; /* Truely asychronous */ |
unsigned char statusByte; /* Status Phase byte */ |
SCSI_Sense_Data senseData; /* Gets Sense data */ |
unsigned long actualTransferCount; /* TRUE transfer length */ |
/* VM state (set by DoSCSIExecIO, cleared by command completion) */ |
VMHoldRecord vmHoldInfo[kVMSize]; |
/* This is used for the setup dialog */ |
Boolean validDevice; |
/* Statistics */ |
UnsignedWide testStartTime; /* Total testing start time */ |
UnsignedWide testEndTime; /* Total testing end time */ |
double sampleSum; /* For mean time (sum in uSec) */ |
double sampleSumSquare; /* And standard deviation */ |
RequestMemoryPtr requestMemoryPtr; /* Current request slot */ |
RequestMemory requestMemory[kRequestMemory]; |
}; |
typedef struct InfoRecord InfoRecord, *InfoPtr; |
/* |
* Processing functions |
*/ |
void GetDevicesToTest(void); |
void DisplayTestParameters(void); |
void DisplayTestResults(void); |
void StartTesting(void); |
void ContinueTesting(void); |
pascal Boolean NumericFilter( |
DialogPtr dp, |
EventRecord *eventPtr, |
short *itemHit |
); |
/* |
* SCSI Executor |
*/ |
OSErr DoSCSISynchronousIO( |
InfoPtr infoPtr, |
SCSI_CommandPtr commandPtr, |
unsigned long scsiFlags, |
Ptr bufferPtr, |
unsigned long transferLength |
); |
short GetSCSICDBLength( |
const SCSI_CommandPtr scsiCommandPtr |
); |
/* |
* Utility functions |
*/ |
OSErr CheckForDevicePresent( |
unsigned short busID, |
unsigned short target, |
unsigned short LUN |
); |
Boolean AsyncSCSIPresent(void); |
OSErr GetHostBusCount( |
short *busCount |
); |
void DoTestUnitReady( |
unsigned short busID, |
unsigned short target, |
unsigned short LUN |
); |
void ExecuteSCSICommand( |
register InfoPtr infoPtr |
); |
void IOCompletion( |
SCSIExecIOPB *ioPBPtr |
); |
/* |
* Display and error logging |
*/ |
void DisplayDeviceInfo( |
register InfoPtr infoPtr |
); |
void AppendSCSIBusID( |
StringPtr result, |
DeviceIdent deviceIdent |
); |
void ShowSCSIBusID( |
register InfoPtr infoPtr |
); |
void ShowRequestSense( |
register InfoPtr infoPtr |
); |
void ShowStatusError( |
OSErr errorStatus, |
unsigned short cmdByte |
); |
void DisplaySCSIErrorMessage( |
OSErr errorStatus, |
ConstStr255Param errorText |
); |
void NonFatalError( |
OSErr errorStatus, |
ConstStr255Param errorMsg |
); |
void FatalError( |
OSErr errorStatus, |
ConstStr255Param errorMsg |
); |
/* |
* String formatting utilities. |
*/ |
/* |
* AppendChar writes a character into the string. Note that |
* it wraps around if the string size exceeds 255 bytes. |
*/ |
#define AppendChar(result, c) (result[++result[0]] = (c)) |
void AppendUnsigned( |
StringPtr result, |
unsigned long value |
); |
void AppendSigned( |
StringPtr result, |
signed long value |
); |
void AppendUnsignedLeadingZeros( |
StringPtr result, |
unsigned long value, |
short fieldWidth, |
short terminatorChar |
); |
void AppendHexLeadingZeros( |
StringPtr result, |
unsigned long value, |
short fieldWidth |
); |
void AppendUnsignedInField( |
StringPtr result, |
unsigned long value, |
short fieldWidth |
); |
void AppendBytes( |
StringPtr result, |
const Ptr source, |
unsigned short length |
); |
void AppendPascalString( |
StringPtr result, |
const StringPtr value |
); |
void AppendCString( |
StringPtr result, |
const char *source, |
unsigned short maxLength /* Ignored if zero */ |
); |
void AppendOSType( |
StringPtr result, |
OSType value |
); |
void AppendDouble( |
StringPtr result, |
double value, |
unsigned short decimalPlaces |
); |
/* |
* Window Utilities |
*/ |
void DoZoomWindow( |
WindowPtr theWindow, |
short whichPart |
); |
Boolean DoGrowWindow( |
WindowPtr theWindow, |
Point eventWhere, |
short minimumWidth, |
short minimumHeight |
); |
void MyDrawGrowIcon( |
WindowPtr theWindow |
); |
/* |
* Format a block of data into the log. |
*/ |
void DisplayDataBlock( |
Ptr dataPtr, |
unsigned short dataLength |
); |
void pstrcpy( |
StringPtr destination, |
ConstStr255Param source |
); |
void pstrcat( |
StringPtr destination, |
ConstStr255Param source |
); |
void ClearMemory( |
Ptr dataPtr, |
unsigned long dataSize |
); |
#define width(r) ((r).right - (r).left) |
#define height(r) ((r).bottom - (r).top) |
#define CLEAR(record) ClearMemory((Ptr) &record, sizeof record); |
/* |
* Global variables. |
*/ |
EXTERN WindowPtr gMainWindow; |
EXTERN EventRecord gCurrentEvent; |
#define EVENT (gCurrentEvent) |
EXTERN ListHandle gLogListHandle; |
EXTERN THPrint gPrintHandle; |
EXTERN Boolean gQuitNow; |
EXTERN Boolean gStopNow; |
EXTERN Boolean gUpdateMenusNeeded; |
EXTERN Boolean gInForeground; |
EXTERN Boolean gVirtualMemoryEnabled; |
EXTERN MenuHandle gAppleMenu; |
EXTERN MenuHandle gFileMenu; |
EXTERN MenuHandle gEditMenu; |
EXTERN short gMaxHostBus; |
EXTERN QHdr infoPtrQueue; /* Known execution threads */ |
/* |
* VM Stuff |
*/ |
extern void VMStartMarker(void); |
extern void VMEndMarker(void); |
#define kVMStackSize 4096 |
EXTERN VMHoldRecord gVMHoldRecord[kVMStack + 1]; |
#endif /* REZ */ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14