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