1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
/*
File: MacSCSICommand.h
Contains: SCSI specific definitions.
Written by: Martin Minow
*/
/*
* Copyright 1995, 1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Scsi-specific definitions.
*/
#ifndef __MacSCSICommand__
#define __MacSCSICommand__
/*
* 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 SCSI_Inquiry_Data.devTypeMod
*/
enum {
kScsiInquiryRMB = 0x80 /* Removable medium if set */
};
/*
* These bits may be set in SCSI_Inquiry_Data.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 */
};
/*
* These bits may be set in SCSI_Inquiry_Data.devType
*/
enum {
kScsiDevTypeDirect = 0,
kScsiDevTypeSequential,
kScsiDevTypePrinter,
kScsiDevTypeProcessor,
kScsiDevTypeWorm, /* Write-once, read mult */
kScsiDevTypeCDROM,
kScsiDevTypeScanner,
kScsiDevTypeOptical,
kScsiDevTypeChanger,
kScsiDevTypeComm,
kScsiDevTypeGraphicArts0A,
kScsiDevTypeGraphicArts0B,
kScsiDevTypeFirstReserved, /* Reserved sequence start */
kScsiDevTypeUnknownOrMissing = 0x1F,
kScsiDevTypeMask = 0x1F
};
/*
* These are device type qualifiers. 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 kScsiCmdModeSelect10 0x55
#define kScsiCmdModeSelect6 0x15
#define kScsiCmdModeSense10 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).
*/
#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 kScsiMsgEnableDisconnectMask 0x40
#define kScsiMsgTwoByte 0x20
#define kScsiMsgTwoByteMin 0x20
#define kScsiMsgTwoByteMax 0x2f
/*
* Default timeout times for SCSI commands (times are in Msec).
*/
#define kScsiNormalCompletionTime (500L) /* 1/2 second */
/*
* Dratted DAT tape.
*/
#define kScsiDATCompletionTime (60L * 1000L); /* One minute */
/*
* Yes, we do allow 90 seconds for spin-up of those dratted tape drives.
*/
#define kScsiSpinUpCompletionTime (90L * 1000L)
#endif /* __MacSCSICommand__ */
|