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__ */ |