1/* 2 File: MacSCSICommand.h 3 4 Contains: SCSI specific definitions. 5 6 Written by: Martin Minow 7 8*/ 9 10/* 11 * Copyright 1995, 1997 by Apple Computer, Inc. 12 * All Rights Reserved 13 * 14 * Permission to use, copy, modify, and distribute this software and 15 * its documentation for any purpose and without fee is hereby granted, 16 * provided that the above copyright notice appears in all copies and 17 * that both the copyright notice and this permission notice appear in 18 * supporting documentation. 19 * 20 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE. 23 * 24 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 25 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 26 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 27 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 28 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 29 */ 30 31/* 32 * Scsi-specific definitions. 33 */ 34#ifndef __MacSCSICommand__ 35#define __MacSCSICommand__ 36 37/* 38 * The 6-byte commands are used for most simple 39 * I/O requests. 40 */ 41struct SCSI_6_Byte_Command { /* Six-byte command */ 42 unsigned char opcode; /* 0 */ 43 unsigned char lbn3; /* 1 lbn in low 5 */ 44 unsigned char lbn2; /* 2 */ 45 unsigned char lbn1; /* 3 */ 46 unsigned char len; /* 4 */ 47 unsigned char ctrl; /* 5 */ 48}; 49typedef struct SCSI_6_Byte_Command SCSI_6_Byte_Command; 50 51struct SCSI_10_Byte_Command { /* Ten-byte command */ 52 unsigned char opcode; /* 0 */ 53 unsigned char lun; /* 1 */ 54 unsigned char lbn4; /* 2 */ 55 unsigned char lbn3; /* 3 */ 56 unsigned char lbn2; /* 4 */ 57 unsigned char lbn1; /* 5 */ 58 unsigned char pad; /* 6 */ 59 unsigned char len2; /* 7 */ 60 unsigned char len1; /* 8 */ 61 unsigned char ctrl; /* 9 */ 62}; 63typedef struct SCSI_10_Byte_Command SCSI_10_Byte_Command; 64 65struct SCSI_12_Byte_Command { /* Twelve-byte command */ 66 unsigned char opcode; /* 0 */ 67 unsigned char lun; /* 1 */ 68 unsigned char lbn4; /* 2 */ 69 unsigned char lbn3; /* 3 */ 70 unsigned char lbn2; /* 4 */ 71 unsigned char lbn1; /* 5 */ 72 unsigned char len4; /* 6 */ 73 unsigned char len3; /* 7 */ 74 unsigned char len2; /* 8 */ 75 unsigned char len1; /* 9 */ 76 unsigned char pad; /* 10 */ 77 unsigned char ctrl; /* 11 */ 78}; 79typedef struct SCSI_12_Byte_Command SCSI_12_Byte_Command; 80 81/* 82 * This union defines all scsi commands. 83 */ 84union SCSI_Command { 85 SCSI_6_Byte_Command scsi6; 86 SCSI_10_Byte_Command scsi10; 87 SCSI_12_Byte_Command scsi12; 88 unsigned char scsi[12]; 89}; 90typedef union SCSI_Command SCSI_Command, *SCSI_CommandPtr; 91 92/* 93 * Returned by a read-capacity command. 94 */ 95struct SCSI_Capacity_Data { 96 unsigned char lbn4; /* Number */ 97 unsigned char lbn3; /* of */ 98 unsigned char lbn2; /* logical */ 99 unsigned char lbn1; /* blocks */ 100 unsigned char len4; /* Length */ 101 unsigned char len3; /* of each */ 102 unsigned char len2; /* logical block */ 103 unsigned char len1; /* in bytes */ 104}; 105typedef struct SCSI_Capacity_Data SCSI_Capacity_Data; 106 107struct SCSI_Inquiry_Data { /* Inquiry returns this */ 108 unsigned char devType; /* 0 Device type, */ 109 unsigned char devTypeMod; /* 1 Device type modifier */ 110 unsigned char version; /* 2 ISO/ECMA/ANSI version */ 111 unsigned char format; /* 3 Response data format */ 112 unsigned char length; /* 4 Additional Length */ 113 unsigned char reserved5; /* 5 Reserved */ 114 unsigned char reserved6; /* 6 Reserved */ 115 unsigned char flags; /* 7 Capability flags */ 116 unsigned char vendor[8]; /* 8-15 Vendor-specific */ 117 unsigned char product[16]; /* 16-31 Product id */ 118 unsigned char revision[4]; /* 32-35 Product revision */ 119 unsigned char vendorSpecific[20]; /* 36-55 Vendor stuff */ 120 unsigned char moreReserved[40]; /* 56-95 Reserved */ 121}; 122typedef struct SCSI_Inquiry_Data SCSI_Inquiry_Data; 123 124/* 125 * This bit may be set in SCSI_Inquiry_Data.devTypeMod 126 */ 127enum { 128 kScsiInquiryRMB = 0x80 /* Removable medium if set */ 129}; 130/* 131 * These bits may be set in SCSI_Inquiry_Data.flags 132 */ 133enum { 134 kScsiInquiryRelAdr = 0x80, /* Has relative addressing */ 135 kScsiInquiryWBus32 = 0x40, /* Wide (32-bit) transfers */ 136 kScsiInquiryWBus16 = 0x20, /* Wide (16-bit) transfers */ 137 kScsiInquirySync = 0x10, /* Synchronous transfers */ 138 kScsiInquiryLinked = 0x08, /* Linked commands ok */ 139 kScsiInquiryReserved = 0x04, 140 kScsiInquiryCmdQue = 0x02, /* Tagged cmd queuing ok */ 141 kScsiInquirySftRe = 0x01 /* Soft reset alternative */ 142}; 143 144/* 145 * These bits may be set in SCSI_Inquiry_Data.devType 146 */ 147enum { 148 kScsiDevTypeDirect = 0, 149 kScsiDevTypeSequential, 150 kScsiDevTypePrinter, 151 kScsiDevTypeProcessor, 152 kScsiDevTypeWorm, /* Write-once, read mult */ 153 kScsiDevTypeCDROM, 154 kScsiDevTypeScanner, 155 kScsiDevTypeOptical, 156 kScsiDevTypeChanger, 157 kScsiDevTypeComm, 158 kScsiDevTypeGraphicArts0A, 159 kScsiDevTypeGraphicArts0B, 160 kScsiDevTypeFirstReserved, /* Reserved sequence start */ 161 kScsiDevTypeUnknownOrMissing = 0x1F, 162 kScsiDevTypeMask = 0x1F 163}; 164/* 165 * These are device type qualifiers. We need them to distinguish between "unknown" 166 * and "missing" devices. 167 */ 168enum { 169 kScsiDevTypeQualifierConnected = 0x00, /* Exists and is connected */ 170 kScsiDevTypeQualifierNotConnected = 0x20, /* Logical unit exists */ 171 kScsiDevTypeQualifierReserved = 0x40, 172 kScsiDevTypeQualifierMissing = 0x60, /* No such logical unit */ 173 kScsiDevTypeQualifierVendorSpecific = 0x80, /* Other bits are unspecified */ 174 kScsiDevTypeQualifierMask = 0xE0 175}; 176#define kScsiDevTypeMissing \ 177 (kScsiDevTypeUnknownOrMissing | kScsiDevTypeQualifierMissing) 178 179/* 180 * This is the data that is returned after a GetExtendedStatus 181 * request. The errorCode gives a general indication of the error, 182 * which may be qualified by the additionalSenseCode and 183 * additionalSenseQualifier fields. These may be device (vendor) 184 * specific values, however. The info[] field contains additional 185 * information. For a media error, it contains the failing 186 * logical block number (most-significant byte first). 187 */ 188struct SCSI_Sense_Data { /* Request Sense result */ 189 unsigned char errorCode; /* 0 Class code, valid lbn */ 190 unsigned char segmentNumber; /* 1 Segment number */ 191 unsigned char senseKey; /* 2 Sense key and flags */ 192 unsigned char info[4]; 193 unsigned char additionalSenseLength; 194 unsigned char reservedForCopy[4]; 195 unsigned char additionalSenseCode; 196 unsigned char additionalSenseQualifier; 197 unsigned char fruCode; /* Field replacable unit code */ 198 unsigned char senseKeySpecific[2]; 199 unsigned char additional[101]; 200}; 201typedef struct SCSI_Sense_Data SCSI_Sense_Data; 202/* 203 * The high-bit of errorCode signals whether there is a logical 204 * block. The low value signals whether there is a valid sense 205 */ 206#define kScsiSenseHasLBN 0x80 /* Logical block number set */ 207#define kScsiSenseInfoValid 0x70 /* Is sense key valid? */ 208#define kScsiSenseInfoMask 0x70 /* Mask for sense info */ 209/* 210 * These bits may be set in the sense key 211 */ 212#define kScsiSenseKeyMask 0x0F 213#define kScsiSenseILI 0x20 /* Illegal logical Length */ 214#define kScsiSenseEOM 0x40 /* End of media */ 215#define kScsiSenseFileMark 0x80 /* End of file mark */ 216 217/* 218 * SCSI sense codes. (Returned after request sense). 219 */ 220#define kScsiSenseNone 0x00 /* No error */ 221#define kScsiSenseRecoveredErr 0x01 /* Warning */ 222#define kScsiSenseNotReady 0x02 /* Device not ready */ 223#define kScsiSenseMediumErr 0x03 /* Device medium error */ 224#define kScsiSenseHardwareErr 0x04 /* Device hardware error */ 225#define kScsiSenseIllegalReq 0x05 /* Illegal request for dev. */ 226#define kScsiSenseUnitAtn 0x06 /* Unit attention (not err) */ 227#define kScsiSenseDataProtect 0x07 /* Data protection */ 228#define kScsiSenseBlankCheck 0x08 /* Tape-specific error */ 229#define kScsiSenseVendorSpecific 0x09 /* Vendor-specific error */ 230#define kScsiSenseCopyAborted 0x0a /* Copy request cancelled */ 231#define kScsiSenseAbortedCmd 0x0b /* Initiator aborted cmd. */ 232#define kScsiSenseEqual 0x0c /* Comparison equal */ 233#define kScsiSenseVolumeOverflow 0x0d /* Write past end mark */ 234#define kScsiSenseMiscompare 0x0e /* Comparison failed */ 235#define kScsiSenseCurrentErr 0x70 236#define kScsiSenseDeferredErr 0x71 237 238/* 239 * Mode sense parameter header 240 */ 241struct SCSI_ModeParamHeader { 242 unsigned char modeDataLength; 243 unsigned char mediumType; 244 unsigned char deviceSpecific; 245 unsigned char blockDescriptorLength; 246}; 247typedef struct SCSI_ModeParamHeader SCSI_ModeParamHeader; 248 249struct SCSI_ModeParamBlockDescriptor { 250 unsigned char densityCode; 251 unsigned char numberOfBlocks[3]; 252 unsigned char reserved; 253 unsigned char blockLength[3]; 254}; 255typedef struct SCSI_ModeParamBlockDescriptor SCSI_ModeParamBlockDescriptor; 256 257union SCSI_ModeParamPage { 258 unsigned char data[1]; 259 struct { 260 unsigned char code; 261 unsigned char length; 262 } page; 263}; 264typedef union SCSI_ModeParamPage SCSI_ModeParamPage; 265 266/* 267 * LogSense parameter header 268 */ 269struct SCSI_LogSenseParamHeader { 270 unsigned char pageCode; 271 unsigned char reserved; 272 unsigned char pageLength[2]; 273}; 274typedef struct SCSI_LogSenseParamHeader SCSI_LogSenseParamHeader; 275 276/* 277 * Log parameter pages are variable-length with a fixed length header. 278 */ 279union SCSI_LogSenseParamPage { 280 unsigned char data[1]; 281 struct { 282 unsigned char parameterCode[2]; 283 unsigned char flags; 284 unsigned char parameterLength; 285 } page; 286}; 287typedef union SCSI_LogSenseParamPage SCSI_LogSenseParamPage; 288 289/* 290 * SCSI command status (from status phase) 291 */ 292#define kScsiStatusGood 0x00 /* Normal completion */ 293#define kScsiStatusCheckCondition 0x02 /* Need GetExtendedStatus */ 294#define kScsiStatusConditionMet 0x04 295#define kScsiStatusBusy 0x08 /* Device busy (self-test?) */ 296#define kScsiStatusIntermediate 0x10 /* Intermediate status */ 297#define kScsiStatusResConflict 0x18 /* Reservation conflict */ 298#define kScsiStatusQueueFull 0x28 /* Target can't do command */ 299#define kScsiStatusReservedMask 0x3e /* Vendor specific? */ 300 301/* 302 * SCSI command codes. Commands defined as ...6, ...10, ...12, are 303 * six-byte, ten-byte, and twelve-byte variants of the indicated command. 304 */ 305/* 306 * These commands are supported for all devices. 307 */ 308#define kScsiCmdChangeDefinition 0x40 309#define kScsiCmdCompare 0x39 310#define kScsiCmdCopy 0x18 311#define kScsiCmdCopyAndVerify 0x3a 312#define kScsiCmdInquiry 0x12 313#define kScsiCmdLogSelect 0x4c 314#define kScsiCmdLogSense 0x4d 315#define kScsiCmdModeSelect10 0x55 316#define kScsiCmdModeSelect6 0x15 317#define kScsiCmdModeSense10 0x5a 318#define kScsiCmdModeSense6 0x1a 319#define kScsiCmdReadBuffer 0x3c 320#define kScsiCmdRecvDiagResult 0x1c 321#define kScsiCmdRequestSense 0x03 322#define kScsiCmdSendDiagnostic 0x1d 323#define kScsiCmdTestUnitReady 0x00 324#define kScsiCmdWriteBuffer 0x3b 325 326/* 327 * These commands are supported by direct-access devices only. 328 */ 329#define kScsiCmdFormatUnit 0x04 330#define kSCSICmdCopy 0x18 331#define kSCSICmdCopyAndVerify 0x3a 332#define kScsiCmdLockUnlockCache 0x36 333#define kScsiCmdPrefetch 0x34 334#define kScsiCmdPreventAllowRemoval 0x1e 335#define kScsiCmdRead6 0x08 336#define kScsiCmdRead10 0x28 337#define kScsiCmdReadCapacity 0x25 338#define kScsiCmdReadDefectData 0x37 339#define kScsiCmdReadLong 0x3e 340#define kScsiCmdReassignBlocks 0x07 341#define kScsiCmdRelease 0x17 342#define kScsiCmdReserve 0x16 343#define kScsiCmdRezeroUnit 0x01 344#define kScsiCmdSearchDataEql 0x31 345#define kScsiCmdSearchDataHigh 0x30 346#define kScsiCmdSearchDataLow 0x32 347#define kScsiCmdSeek6 0x0b 348#define kScsiCmdSeek10 0x2b 349#define kScsiCmdSetLimits 0x33 350#define kScsiCmdStartStopUnit 0x1b 351#define kScsiCmdSynchronizeCache 0x35 352#define kScsiCmdVerify 0x2f 353#define kScsiCmdWrite6 0x0a 354#define kScsiCmdWrite10 0x2a 355#define kScsiCmdWriteAndVerify 0x2e 356#define kScsiCmdWriteLong 0x3f 357#define kScsiCmdWriteSame 0x41 358 359/* 360 * These commands are supported by sequential devices. 361 */ 362#define kScsiCmdRewind 0x01 363#define kScsiCmdWriteFilemarks 0x10 364#define kScsiCmdSpace 0x11 365#define kScsiCmdLoadUnload 0x1B 366/* 367 * ANSI SCSI-II for CD-ROM devices. 368 */ 369#define kScsiCmdReadCDTableOfContents 0x43 370 371/* 372 * Message codes (for Msg In and Msg Out phases). 373 */ 374#define kScsiMsgAbort 0x06 375#define kScsiMsgAbortTag 0x0d 376#define kScsiMsgBusDeviceReset 0x0c 377#define kScsiMsgClearQueue 0x0e 378#define kScsiMsgCmdComplete 0x00 379#define kScsiMsgDisconnect 0x04 380#define kScsiMsgIdentify 0x80 381#define kScsiMsgIgnoreWideResdue 0x23 382#define kScsiMsgInitiateRecovery 0x0f 383#define kScsiMsgInitiatorDetectedErr 0x05 384#define kScsiMsgLinkedCmdComplete 0x0a 385#define kScsiMsgLinkedCmdCompleteFlag 0x0b 386#define kScsiMsgParityErr 0x09 387#define kScsiMsgRejectMsg 0x07 388#define kScsiMsgModifyDataPtr 0x00 /* Extended msg */ 389#define kScsiMsgNop 0x08 390#define kScsiMsgHeadOfQueueTag 0x21 /* Two byte msg */ 391#define kScsiMsgOrderedQueueTag 0x22 /* Two byte msg */ 392#define kScsiMsgSimpleQueueTag 0x20 /* Two byte msg */ 393#define kScsiMsgReleaseRecovery 0x10 394#define kScsiMsgRestorePointers 0x03 395#define kScsiMsgSaveDataPointers 0x02 396#define kScsiMsgSyncXferReq 0x01 /* Extended msg */ 397#define kScsiMsgWideDataXferReq 0x03 /* Extended msg */ 398#define kScsiMsgTerminateIOP 0x11 399#define kScsiMsgExtended 0x01 400#define kScsiMsgEnableDisconnectMask 0x40 401 402#define kScsiMsgTwoByte 0x20 403#define kScsiMsgTwoByteMin 0x20 404#define kScsiMsgTwoByteMax 0x2f 405 406/* 407 * Default timeout times for SCSI commands (times are in Msec). 408 */ 409#define kScsiNormalCompletionTime (500L) /* 1/2 second */ 410/* 411 * Dratted DAT tape. 412 */ 413#define kScsiDATCompletionTime (60L * 1000L); /* One minute */ 414/* 415 * Yes, we do allow 90 seconds for spin-up of those dratted tape drives. 416 */ 417#define kScsiSpinUpCompletionTime (90L * 1000L) 418 419 420#endif /* __MacSCSICommand__ */ 421