xref: /netbsd-src/external/bsd/pdisk/dist/MacSCSICommand.h (revision 48a628ae0434c4247b560ad8f2eb1dc06d0dd070)
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  */
41 struct SCSI_6_Byte_Command {                /* Six-byte command         */
42     uint8_t       opcode;             /*  0                       */
43     uint8_t       lbn3;               /*  1 lbn in low 5          */
44     uint8_t       lbn2;               /*  2                       */
45     uint8_t       lbn1;               /*  3                       */
46     uint8_t       len;                /*  4                       */
47     uint8_t       ctrl;               /*  5                       */
48 };
49 typedef struct SCSI_6_Byte_Command SCSI_6_Byte_Command;
50 
51 struct SCSI_10_Byte_Command {               /* Ten-byte command         */
52     uint8_t       opcode;             /*  0                       */
53     uint8_t       lun;                /*  1                       */
54     uint8_t       lbn4;               /*  2                       */
55     uint8_t       lbn3;               /*  3                       */
56     uint8_t       lbn2;               /*  4                       */
57     uint8_t       lbn1;               /*  5                       */
58     uint8_t       pad;                /*  6                       */
59     uint8_t       len2;               /*  7                       */
60     uint8_t       len1;               /*  8                       */
61     uint8_t       ctrl;               /*  9                       */
62 };
63 typedef struct SCSI_10_Byte_Command SCSI_10_Byte_Command;
64 
65 struct SCSI_12_Byte_Command {               /* Twelve-byte command      */
66     uint8_t       opcode;             /*  0                       */
67     uint8_t       lun;                /*  1                       */
68     uint8_t       lbn4;               /*  2                       */
69     uint8_t       lbn3;               /*  3                       */
70     uint8_t       lbn2;               /*  4                       */
71     uint8_t       lbn1;               /*  5                       */
72     uint8_t       len4;               /*  6                       */
73     uint8_t       len3;               /*  7                       */
74     uint8_t       len2;               /*  8                       */
75     uint8_t       len1;               /*  9                       */
76     uint8_t       pad;                /* 10                       */
77     uint8_t       ctrl;               /* 11                       */
78 };
79 typedef struct SCSI_12_Byte_Command SCSI_12_Byte_Command;
80 
81 /*
82  * This union defines all scsi commands.
83  */
84 union SCSI_Command {
85     SCSI_6_Byte_Command     scsi6;
86     SCSI_10_Byte_Command    scsi10;
87     SCSI_12_Byte_Command    scsi12;
88     uint8_t           scsi[12];
89 };
90 typedef union SCSI_Command SCSI_Command, *SCSI_CommandPtr;
91 
92 /*
93  * Returned by a read-capacity command.
94  */
95 struct SCSI_Capacity_Data {
96     uint8_t       lbn4;               /* Number                   */
97     uint8_t       lbn3;               /*  of                      */
98     uint8_t       lbn2;               /*   logical                */
99     uint8_t       lbn1;               /*    blocks                */
100     uint8_t       len4;               /* Length                   */
101     uint8_t       len3;               /*  of each                 */
102     uint8_t       len2;               /*   logical block          */
103     uint8_t       len1;               /*    in bytes              */
104 };
105 typedef struct SCSI_Capacity_Data SCSI_Capacity_Data;
106 
107 struct SCSI_Inquiry_Data {                  /* Inquiry returns this     */
108     uint8_t       devType;            /*  0 Device type,          */
109     uint8_t       devTypeMod;         /*  1 Device type modifier  */
110     uint8_t       version;            /*  2 ISO/ECMA/ANSI version */
111     uint8_t       format;             /*  3 Response data format  */
112     uint8_t       length;             /*  4 Additional Length     */
113     uint8_t       reserved5;          /*  5 Reserved              */
114     uint8_t       reserved6;          /*  6 Reserved              */
115     uint8_t       flags;              /*  7 Capability flags      */
116     uint8_t       vendor[8];          /*  8-15 Vendor-specific    */
117     uint8_t       product[16];        /* 16-31 Product id         */
118     uint8_t       revision[4];        /* 32-35 Product revision   */
119     uint8_t       vendorSpecific[20]; /* 36-55 Vendor stuff       */
120     uint8_t       moreReserved[40];   /* 56-95 Reserved           */
121 };
122 typedef struct SCSI_Inquiry_Data SCSI_Inquiry_Data;
123 
124 /*
125  * This bit may be set in SCSI_Inquiry_Data.devTypeMod
126  */
127 enum {
128     kScsiInquiryRMB = 0x80                  /* Removable medium if set  */
129 };
130 /*
131  * These bits may be set in SCSI_Inquiry_Data.flags
132  */
133 enum {
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  */
147 enum {
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  */
168 enum {
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  */
188 struct SCSI_Sense_Data {                /* Request Sense result         */
189     uint8_t       errorCode;      /*  0   Class code, valid lbn   */
190     uint8_t       segmentNumber;  /*  1   Segment number          */
191     uint8_t       senseKey;       /*  2   Sense key and flags     */
192     uint8_t       info[4];
193     uint8_t       additionalSenseLength;
194     uint8_t       reservedForCopy[4];
195     uint8_t       additionalSenseCode;
196     uint8_t       additionalSenseQualifier;
197     uint8_t       fruCode;        /* Field replacable unit code   */
198     uint8_t       senseKeySpecific[2];
199     uint8_t       additional[101];
200 };
201 typedef 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  */
241 struct SCSI_ModeParamHeader {
242     uint8_t       modeDataLength;
243     uint8_t       mediumType;
244     uint8_t       deviceSpecific;
245     uint8_t       blockDescriptorLength;
246 };
247 typedef struct SCSI_ModeParamHeader SCSI_ModeParamHeader;
248 
249 struct SCSI_ModeParamBlockDescriptor {
250     uint8_t       densityCode;
251     uint8_t       numberOfBlocks[3];
252     uint8_t       reserved;
253     uint8_t       blockLength[3];
254 };
255 typedef struct SCSI_ModeParamBlockDescriptor SCSI_ModeParamBlockDescriptor;
256 
257 union SCSI_ModeParamPage {
258     uint8_t       data[1];
259     struct {
260 	uint8_t   code;
261 	uint8_t   length;
262     } page;
263 };
264 typedef union SCSI_ModeParamPage SCSI_ModeParamPage;
265 
266 /*
267  * LogSense parameter header
268  */
269 struct SCSI_LogSenseParamHeader {
270     uint8_t       pageCode;
271     uint8_t       reserved;
272     uint8_t       pageLength[2];
273 };
274 typedef struct SCSI_LogSenseParamHeader SCSI_LogSenseParamHeader;
275 
276 /*
277  * Log parameter pages are variable-length with a fixed length header.
278  */
279 union SCSI_LogSenseParamPage {
280     uint8_t       data[1];
281     struct {
282 	uint8_t   parameterCode[2];
283 	uint8_t   flags;
284 	uint8_t   parameterLength;
285     } page;
286 };
287 typedef 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