akuker
/scsi_test
/amendments
/4
new file
akuker made amendment 4 over 2 years ago
--- MacSCSICommand.h Tue Jun 16 01:55:46 2009
+++ MacSCSICommand.h Tue Jun 16 01:55:46 2009
@@ -0,0 +1,447 @@
+/* MacScsiCommand.h */
+/*
+ * Scsi-specific definitions.
+ */
+#ifndef __MacSCSICommand__
+#define __MacSCSICommand__
+
+#include <stddef.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
+/*
+ * This uses the new "common" SCSI.h which is not yet in the public
+ * header folders.
+ */
+#include "SCSI.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * The 6-byte commands are used for most simple
+ * I/O requests.
+ */
+struct SCSI_6_Byte_Command { /* Six-byte command */
+ unsigned char opcode; /* 0 */
+ unsigned char lbn3; /* 1 lbn in low 5 */
+ unsigned char lbn2; /* 2 */
+ unsigned char lbn1; /* 3 */
+ unsigned char len; /* 4 */
+ unsigned char ctrl; /* 5 */
+};
+typedef struct SCSI_6_Byte_Command SCSI_6_Byte_Command;
+
+struct SCSI_10_Byte_Command { /* Ten-byte command */
+ unsigned char opcode; /* 0 */
+ unsigned char lun; /* 1 */
+ unsigned char lbn4; /* 2 */
+ unsigned char lbn3; /* 3 */
+ unsigned char lbn2; /* 4 */
+ unsigned char lbn1; /* 5 */
+ unsigned char pad; /* 6 */
+ unsigned char len2; /* 7 */
+ unsigned char len1; /* 8 */
+ unsigned char ctrl; /* 9 */
+};
+typedef struct SCSI_10_Byte_Command SCSI_10_Byte_Command;
+
+struct SCSI_12_Byte_Command { /* Twelve-byte command */
+ unsigned char opcode; /* 0 */
+ unsigned char lun; /* 1 */
+ unsigned char lbn4; /* 2 */
+ unsigned char lbn3; /* 3 */
+ unsigned char lbn2; /* 4 */
+ unsigned char lbn1; /* 5 */
+ unsigned char len4; /* 6 */
+ unsigned char len3; /* 7 */
+ unsigned char len2; /* 8 */
+ unsigned char len1; /* 9 */
+ unsigned char pad; /* 10 */
+ unsigned char ctrl; /* 11 */
+};
+typedef struct SCSI_12_Byte_Command SCSI_12_Byte_Command;
+
+/*
+ * This union defines all scsi commands.
+ */
+union SCSI_Command {
+ SCSI_6_Byte_Command scsi6;
+ SCSI_10_Byte_Command scsi10;
+ SCSI_12_Byte_Command scsi12;
+ unsigned char scsi[12];
+};
+typedef union SCSI_Command SCSI_Command, *SCSI_CommandPtr;
+
+/*
+ * Returned by a read-capacity command.
+ */
+struct SCSI_Capacity_Data {
+ unsigned char lbn4; /* Number */
+ unsigned char lbn3; /* of */
+ unsigned char lbn2; /* logical */
+ unsigned char lbn1; /* blocks */
+ unsigned char len4; /* Length */
+ unsigned char len3; /* of each */
+ unsigned char len2; /* logical block */
+ unsigned char len1; /* in bytes */
+};
+typedef struct SCSI_Capacity_Data SCSI_Capacity_Data;
+
+struct SCSI_Inquiry_Data { /* Inquiry returns this */
+ unsigned char devType; /* 0 Device type, */
+ unsigned char devTypeMod; /* 1 Device type modifier */
+ unsigned char version; /* 2 ISO/ECMA/ANSI version */
+ unsigned char format; /* 3 Response data format */
+ unsigned char length; /* 4 Additional Length */
+ unsigned char reserved5; /* 5 Reserved */
+ unsigned char reserved6; /* 6 Reserved */
+ unsigned char flags; /* 7 Capability flags */
+ unsigned char vendor[8]; /* 8-15 Vendor-specific */
+ unsigned char product[16]; /* 16-31 Product id */
+ unsigned char revision[4]; /* 32-35 Product revision */
+ unsigned char vendorSpecific[20]; /* 36-55 Vendor stuff */
+ unsigned char moreReserved[40]; /* 56-95 Reserved */
+};
+typedef struct SCSI_Inquiry_Data SCSI_Inquiry_Data;
+
+/*
+ * This bit may be set in devTypeMod
+ */
+enum {
+ kScsiInquiryRMB = 0x80 /* Removable medium if set */
+};
+/*
+ * These bits may be set in flags
+ */
+enum {
+ kScsiInquiryRelAdr = 0x80, /* Has relative addressing */
+ kScsiInquiryWBus32 = 0x40, /* Wide (32-bit) transfers */
+ kScsiInquiryWBus16 = 0x20, /* Wide (16-bit) transfers */
+ kScsiInquirySync = 0x10, /* Synchronous transfers */
+ kScsiInquiryLinked = 0x08, /* Linked commands ok */
+ kScsiInquiryReserved = 0x04,
+ kScsiInquiryCmdQue = 0x02, /* Tagged cmd queuing ok */
+ kScsiInquirySftRe = 0x01 /* Soft reset alternative */
+};
+
+enum {
+ kScsiDevTypeDirect = 0,
+ kScsiDevTypeSequential,
+ kScsiDevTypePrinter,
+ kScsiDevTypeProcessor,
+ kScsiDevTypeWorm, /* Write-once, read multiple */
+ kScsiDevTypeCDROM,
+ kScsiDevTypeScanner,
+ kScsiDevTypeOptical,
+ kScsiDevTypeChanger,
+ kScsiDevTypeComm,
+ kScsiDevTypeGraphicArts0A,
+ kScsiDevTypeGraphicArts0B,
+ kScsiDevTypeFirstReserved, /* Start of reserved sequence */
+ kScsiDevTypeUnknownOrMissing = 0x1F,
+ kScsiDevTypeMask = 0x1F
+};
+/*
+ * These are device type modifiers. We need them to distinguish between "unknown"
+ * and "missing" devices.
+ */
+enum {
+ kScsiDevTypeQualifierConnected = 0x00, /* Exists and is connected */
+ kScsiDevTypeQualifierNotConnected = 0x20, /* Logical unit exists */
+ kScsiDevTypeQualifierReserved = 0x40,
+ kScsiDevTypeQualifierMissing = 0x60, /* No such logical unit */
+ kScsiDevTypeQualifierVendorSpecific = 0x80, /* Other bits are unspecified */
+ kScsiDevTypeQualifierMask = 0xE0
+};
+#define kScsiDevTypeMissing \
+ (kScsiDevTypeUnknownOrMissing | kScsiDevTypeQualifierMissing)
+
+/*
+ * This is the data that is returned after a GetExtendedStatus
+ * request. The errorCode gives a general indication of the error,
+ * which may be qualified by the additionalSenseCode and
+ * additionalSenseQualifier fields. These may be device (vendor)
+ * specific values, however. The info[] field contains additional
+ * information. For a media error, it contains the failing
+ * logical block number (most-significant byte first).
+ */
+struct SCSI_Sense_Data { /* Request Sense result */
+ unsigned char errorCode; /* 0 Class code, valid lbn */
+ unsigned char segmentNumber; /* 1 Segment number */
+ unsigned char senseKey; /* 2 Sense key and flags */
+ unsigned char info[4];
+ unsigned char additionalSenseLength;
+ unsigned char reservedForCopy[4];
+ unsigned char additionalSenseCode;
+ unsigned char additionalSenseQualifier;
+ unsigned char fruCode; /* Field replacable unit code */
+ unsigned char senseKeySpecific[2];
+ unsigned char additional[101];
+};
+typedef struct SCSI_Sense_Data SCSI_Sense_Data;
+/*
+ * The high-bit of errorCode signals whether there is a logical
+ * block. The low value signals whether there is a valid sense
+ */
+#define kScsiSenseHasLBN 0x80 /* Logical block number set */
+#define kScsiSenseInfoValid 0x70 /* Is sense key valid? */
+#define kScsiSenseInfoMask 0x70 /* Mask for sense info */
+/*
+ * These bits may be set in the sense key
+ */
+#define kScsiSenseKeyMask 0x0F
+#define kScsiSenseILI 0x20 /* Illegal logical Length */
+#define kScsiSenseEOM 0x40 /* End of media */
+#define kScsiSenseFileMark 0x80 /* End of file mark */
+
+/*
+ * SCSI sense codes. (Returned after request sense).
+ */
+#define kScsiSenseNone 0x00 /* No error */
+#define kScsiSenseRecoveredErr 0x01 /* Warning */
+#define kScsiSenseNotReady 0x02 /* Device not ready */
+#define kScsiSenseMediumErr 0x03 /* Device medium error */
+#define kScsiSenseHardwareErr 0x04 /* Device hardware error */
+#define kScsiSenseIllegalReq 0x05 /* Illegal request for dev. */
+#define kScsiSenseUnitAtn 0x06 /* Unit attention (not err) */
+#define kScsiSenseDataProtect 0x07 /* Data protection */
+#define kScsiSenseBlankCheck 0x08 /* Tape-specific error */
+#define kScsiSenseVendorSpecific 0x09 /* Vendor-specific error */
+#define kScsiSenseCopyAborted 0x0a /* Copy request cancelled */
+#define kScsiSenseAbortedCmd 0x0b /* Initiator aborted cmd. */
+#define kScsiSenseEqual 0x0c /* Comparison equal */
+#define kScsiSenseVolumeOverflow 0x0d /* Write past end mark */
+#define kScsiSenseMiscompare 0x0e /* Comparison failed */
+#define kScsiSenseCurrentErr 0x70
+#define kScsiSenseDeferredErr 0x71
+
+/*
+ * Mode sense parameter header
+ */
+struct SCSI_ModeParamHeader {
+ unsigned char modeDataLength;
+ unsigned char mediumType;
+ unsigned char deviceSpecific;
+ unsigned char blockDescriptorLength;
+};
+typedef struct SCSI_ModeParamHeader SCSI_ModeParamHeader;
+
+struct SCSI_ModeParamBlockDescriptor {
+ unsigned char densityCode;
+ unsigned char numberOfBlocks[3];
+ unsigned char reserved;
+ unsigned char blockLength[3];
+};
+typedef struct SCSI_ModeParamBlockDescriptor SCSI_ModeParamBlockDescriptor;
+
+union SCSI_ModeParamPage {
+ unsigned char data[1];
+ struct {
+ unsigned char code;
+ unsigned char length;
+ } page;
+};
+typedef union SCSI_ModeParamPage SCSI_ModeParamPage;
+
+/*
+ * LogSense parameter header
+ */
+struct SCSI_LogSenseParamHeader {
+ unsigned char pageCode;
+ unsigned char reserved;
+ unsigned char pageLength[2];
+};
+typedef struct SCSI_LogSenseParamHeader SCSI_LogSenseParamHeader;
+
+/*
+ * Log parameter pages are variable-length with a fixed length header.
+ */
+union SCSI_LogSenseParamPage {
+ unsigned char data[1];
+ struct {
+ unsigned char parameterCode[2];
+ unsigned char flags;
+ unsigned char parameterLength;
+ } page;
+};
+typedef union SCSI_LogSenseParamPage SCSI_LogSenseParamPage;
+
+/*
+ * SCSI command status (from status phase)
+ */
+#define kScsiStatusGood 0x00 /* Normal completion */
+#define kScsiStatusCheckCondition 0x02 /* Need GetExtendedStatus */
+#define kScsiStatusConditionMet 0x04
+#define kScsiStatusBusy 0x08 /* Device busy (self-test?) */
+#define kScsiStatusIntermediate 0x10 /* Intermediate status */
+#define kScsiStatusResConflict 0x18 /* Reservation conflict */
+#define kScsiStatusQueueFull 0x28 /* Target can't do command */
+#define kScsiStatusReservedMask 0x3e /* Vendor specific? */
+
+/*
+ * SCSI command codes. Commands defined as ...6, ...10, ...12, are
+ * six-byte, ten-byte, and twelve-byte variants of the indicated command.
+ */
+/*
+ * These commands are supported for all devices.
+ */
+#define kScsiCmdChangeDefinition 0x40
+#define kScsiCmdCompare 0x39
+#define kScsiCmdCopy 0x18
+#define kScsiCmdCopyAndVerify 0x3a
+#define kScsiCmdInquiry 0x12
+#define kScsiCmdLogSelect 0x4c
+#define kScsiCmdLogSense 0x4d
+#define kScsiCmdModeSelect12 0x55
+#define kScsiCmdModeSelect6 0x15
+#define kScsiCmdModeSense12 0x5a
+#define kScsiCmdModeSense6 0x1a
+#define kScsiCmdReadBuffer 0x3c
+#define kScsiCmdRecvDiagResult 0x1c
+#define kScsiCmdRequestSense 0x03
+#define kScsiCmdSendDiagnostic 0x1d
+#define kScsiCmdTestUnitReady 0x00
+#define kScsiCmdWriteBuffer 0x3b
+
+/*
+ * These commands are supported by direct-access devices only.
+ */
+#define kScsiCmdFormatUnit 0x04
+#define kSCSICmdCopy 0x18
+#define kSCSICmdCopyAndVerify 0x3a
+#define kScsiCmdLockUnlockCache 0x36
+#define kScsiCmdPrefetch 0x34
+#define kScsiCmdPreventAllowRemoval 0x1e
+#define kScsiCmdRead6 0x08
+#define kScsiCmdRead10 0x28
+#define kScsiCmdReadCapacity 0x25
+#define kScsiCmdReadDefectData 0x37
+#define kScsiCmdReadLong 0x3e
+#define kScsiCmdReassignBlocks 0x07
+#define kScsiCmdRelease 0x17
+#define kScsiCmdReserve 0x16
+#define kScsiCmdRezeroUnit 0x01
+#define kScsiCmdSearchDataEql 0x31
+#define kScsiCmdSearchDataHigh 0x30
+#define kScsiCmdSearchDataLow 0x32
+#define kScsiCmdSeek6 0x0b
+#define kScsiCmdSeek10 0x2b
+#define kScsiCmdSetLimits 0x33
+#define kScsiCmdStartStopUnit 0x1b
+#define kScsiCmdSynchronizeCache 0x35
+#define kScsiCmdVerify 0x2f
+#define kScsiCmdWrite6 0x0a
+#define kScsiCmdWrite10 0x2a
+#define kScsiCmdWriteAndVerify 0x2e
+#define kScsiCmdWriteLong 0x3f
+#define kScsiCmdWriteSame 0x41
+
+/*
+ * These commands are supported by sequential devices.
+ */
+#define kScsiCmdRewind 0x01
+#define kScsiCmdWriteFilemarks 0x10
+#define kScsiCmdSpace 0x11
+#define kScsiCmdLoadUnload 0x1B
+/*
+ * ANSI SCSI-II for CD-ROM devices.
+ */
+#define kScsiCmdReadCDTableOfContents 0x43
+
+/*
+ * Message codes (for Msg In and Msg Out phases). The Macintosh
+ * SCSI Manager can't really deal with these.
+ */
+#define kScsiMsgAbort 0x06
+#define kScsiMsgAbortTag 0x0d
+#define kScsiMsgBusDeviceReset 0x0c
+#define kScsiMsgClearQueue 0x0e
+#define kScsiMsgCmdComplete 0x00
+#define kScsiMsgDisconnect 0x04
+#define kScsiMsgIdentify 0x80
+#define kScsiMsgIgnoreWideResdue 0x23
+#define kScsiMsgInitiateRecovery 0x0f
+#define kScsiMsgInitiatorDetectedErr 0x05
+#define kScsiMsgLinkedCmdComplete 0x0a
+#define kScsiMsgLinkedCmdCompleteFlag 0x0b
+#define kScsiMsgParityErr 0x09
+#define kScsiMsgRejectMsg 0x07
+#define kScsiMsgModifyDataPtr 0x00 /* Extended msg */
+#define kScsiMsgNop 0x08
+#define kScsiMsgHeadOfQueueTag 0x21 /* Two byte msg */
+#define kScsiMsgOrderedQueueTag 0x22 /* Two byte msg */
+#define kScsiMsgSimpleQueueTag 0x20 /* Two byte msg */
+#define kScsiMsgReleaseRecovery 0x10
+#define kScsiMsgRestorePointers 0x03
+#define kScsiMsgSaveDataPointers 0x02
+#define kScsiMsgSyncXferReq 0x01 /* Extended msg */
+#define kScsiMsgWideDataXferReq 0x03 /* Extended msg */
+#define kScsiMsgTerminateIOP 0x11
+#define kScsiMsgExtended 0x01
+
+#define kScsiMsgTwoByte 0x20
+#define kScsiMsgTwoByteMin 0x20
+#define kScsiMsgTwoByteMax 0x2f
+
+/*
+ * Default timeout times for SCSI commands.
+ */
+#define kScsiNormalCompletionTime (30L) /* 1/2 second */
+/*
+ * Dratted DAT tape.
+ */
+#define kScsiDATCompletionTime (60L * 60L); /* One minute */
+/*
+ * Yes, we do allow 90 seconds for spin-up of those dratted tape drives.
+ */
+#define kScsiSpinUpCompletionTime (60L * 90L)
+
+/*
+ * The NCR Bits, as returned by ScsiStat are only useful for maintenence
+ * and testing. Only the following bits are valid in the current
+ * implementation of the SCSI Manager. There is no guarantee that the
+ * bits are accessable, or useful, in future SCSI implementations.
+ * Note, however, that the Asynchronous SCSI Manager sets these bits to
+ * correspond to its current internal state.
+ *
+ * Using these bits, the following implications can be drawn:
+ * kScsiStatBSY Bus is busy. (On systems with multiple busses,
+ * there is no indication which bus is busy.)
+ * kScsiStatREQ Bus is busy. There is no way to determine whether
+ * the target has changed phase or has set REQ.
+ * Bus Phase If kScsiStatREQ and kSCSIStatBSY are set, the
+ * phase bits will indicate the current bus phase
+ * from the point of view of the initiator. It may
+ * not necessarily correspond exactly to the hardware
+ * bus phase.
+ */
+#define kScsiStatBSY (1 << 6) /* Bus Busy */
+#define kScsiStatREQ (1 << 5) /* Set if Bus Busy */
+#define kScsiStatMSG (1 << 4) /* MSG phase bit */
+#define kScsiStatCD (1 << 3) /* C/D phase bit */
+#define kScsiStatIO (1 << 2) /* I/O phase bit */
+#define kScsiStatSEL (1 << 1) /* Select phase bit */
+#define kScsiPhaseMask (kScsiStatMSG | kScsiStatCD | kScsiStatIO)
+#define kScsiPhaseShift (2)
+#define ScsiBusPhase(x) (((x) & kScsiPhaseMask) >> kScsiPhaseShift)
+
+/*
+ * The phases are defined by a combination of bus lines. Note: these values
+ * have already been shifted. Other values are undefined. This is really
+ * only useful for the original SCSI manager.
+ */
+#define kScsiPhaseDATO 0 /* Data output (host -> device) */
+#define kScsiPhaseDATI 1 /* Data input (device -> host) */
+#define kScsiPhaseCMD 2 /* Command */
+#define kScsiPhaseSTS 3 /* Status */
+#define kScsiPhaseMSGO 6 /* Message output */
+#define kScsiPhaseMSGI 7 /* Message input */
+
+#endif /* __MacSCSICommand__ */