Home | History | Annotate | Line # | Download | only in dist
      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