AmendHub

Download

akuker

/

scsi_test

/

MacSCSICommand.h

 

(View History)

akuker   new file Latest amendment: 4 on 2022-08-21

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