ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

atapi.h
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Storage Stack
00003  * LICENSE:         DDK - see license.txt in the root dir
00004  * FILE:            drivers/storage/atapi/atapi.h
00005  * PURPOSE:         ATAPI IDE miniport driver
00006  * PROGRAMMERS:     Based on a source code sample from Microsoft NT4 DDK
00007  */
00008 
00009 #include <srb.h>
00010 #include <scsi.h>
00011 
00012 //
00013 // IDE register definition
00014 //
00015 
00016 typedef struct _IDE_REGISTERS_1 {
00017     USHORT Data;
00018     UCHAR BlockCount;
00019     UCHAR BlockNumber;
00020     UCHAR CylinderLow;
00021     UCHAR CylinderHigh;
00022     UCHAR DriveSelect;
00023     UCHAR Command;
00024 } IDE_REGISTERS_1, *PIDE_REGISTERS_1;
00025 
00026 typedef struct _IDE_REGISTERS_2 {
00027     UCHAR AlternateStatus;
00028     UCHAR DriveAddress;
00029 } IDE_REGISTERS_2, *PIDE_REGISTERS_2;
00030 
00031 typedef struct _IDE_REGISTERS_3 {
00032     ULONG Data;
00033     UCHAR Others[4];
00034 } IDE_REGISTERS_3, *PIDE_REGISTERS_3;
00035 
00036 //
00037 // Device Extension Device Flags
00038 //
00039 
00040 #define DFLAGS_DEVICE_PRESENT        0x0001    // Indicates that some device is present.
00041 #define DFLAGS_ATAPI_DEVICE          0x0002    // Indicates whether Atapi commands can be used.
00042 #define DFLAGS_TAPE_DEVICE           0x0004    // Indicates whether this is a tape device.
00043 #define DFLAGS_INT_DRQ               0x0008    // Indicates whether device interrupts as DRQ is set after
00044                                                // receiving Atapi Packet Command
00045 #define DFLAGS_REMOVABLE_DRIVE       0x0010    // Indicates that the drive has the 'removable' bit set in
00046                                                // identify data (offset 128)
00047 #define DFLAGS_MEDIA_STATUS_ENABLED  0x0020    // Media status notification enabled
00048 #define DFLAGS_ATAPI_CHANGER         0x0040    // Indicates atapi 2.5 changer present.
00049 #define DFLAGS_SANYO_ATAPI_CHANGER   0x0080    // Indicates multi-platter device, not conforming to the 2.5 spec.
00050 #define DFLAGS_CHANGER_INITED        0x0100    // Indicates that the init path for changers has already been done.
00051 //
00052 // Used to disable 'advanced' features.
00053 //
00054 
00055 #define MAX_ERRORS                     4
00056 
00057 //
00058 // ATAPI command definitions
00059 //
00060 
00061 #define ATAPI_MODE_SENSE   0x5A
00062 #define ATAPI_MODE_SELECT  0x55
00063 #define ATAPI_FORMAT_UNIT  0x24
00064 
00065 //
00066 // ATAPI Command Descriptor Block
00067 //
00068 
00069 typedef struct _MODE_SENSE_10 {
00070         UCHAR OperationCode;
00071         UCHAR Reserved1;
00072         UCHAR PageCode : 6;
00073         UCHAR Pc : 2;
00074         UCHAR Reserved2[4];
00075         UCHAR ParameterListLengthMsb;
00076         UCHAR ParameterListLengthLsb;
00077         UCHAR Reserved3[3];
00078 } MODE_SENSE_10, *PMODE_SENSE_10;
00079 
00080 typedef struct _MODE_SELECT_10 {
00081         UCHAR OperationCode;
00082         UCHAR Reserved1 : 4;
00083         UCHAR PFBit : 1;
00084         UCHAR Reserved2 : 3;
00085         UCHAR Reserved3[5];
00086         UCHAR ParameterListLengthMsb;
00087         UCHAR ParameterListLengthLsb;
00088         UCHAR Reserved4[3];
00089 } MODE_SELECT_10, *PMODE_SELECT_10;
00090 
00091 typedef struct _MODE_PARAMETER_HEADER_10 {
00092     UCHAR ModeDataLengthMsb;
00093     UCHAR ModeDataLengthLsb;
00094     UCHAR MediumType;
00095     UCHAR Reserved[5];
00096 }MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10;
00097 
00098 //
00099 // IDE command definitions
00100 //
00101 
00102 #define IDE_COMMAND_ATAPI_RESET      0x08
00103 #define IDE_COMMAND_RECALIBRATE      0x10
00104 #define IDE_COMMAND_READ             0x20
00105 #define IDE_COMMAND_WRITE            0x30
00106 #define IDE_COMMAND_VERIFY           0x40
00107 #define IDE_COMMAND_SEEK             0x70
00108 #define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91
00109 #define IDE_COMMAND_ATAPI_PACKET     0xA0
00110 #define IDE_COMMAND_ATAPI_IDENTIFY   0xA1
00111 #define IDE_COMMAND_READ_MULTIPLE    0xC4
00112 #define IDE_COMMAND_WRITE_MULTIPLE   0xC5
00113 #define IDE_COMMAND_SET_MULTIPLE     0xC6
00114 #define IDE_COMMAND_READ_DMA         0xC8
00115 #define IDE_COMMAND_WRITE_DMA             0xCA
00116 #define IDE_COMMAND_GET_MEDIA_STATUS      0xDA
00117 #define IDE_COMMAND_ENABLE_MEDIA_STATUS   0xEF
00118 #define IDE_COMMAND_IDENTIFY              0xEC
00119 #define IDE_COMMAND_MEDIA_EJECT           0xED
00120 
00121 //
00122 // IDE status definitions
00123 //
00124 
00125 #define IDE_STATUS_ERROR             0x01
00126 #define IDE_STATUS_INDEX             0x02
00127 #define IDE_STATUS_CORRECTED_ERROR   0x04
00128 #define IDE_STATUS_DRQ               0x08
00129 #define IDE_STATUS_DSC               0x10
00130 #define IDE_STATUS_DRDY              0x40
00131 #define IDE_STATUS_IDLE              0x50
00132 #define IDE_STATUS_BUSY              0x80
00133 
00134 //
00135 // IDE drive select/head definitions
00136 //
00137 
00138 #define IDE_DRIVE_SELECT_1           0xA0
00139 #define IDE_DRIVE_SELECT_2           0x10
00140 
00141 //
00142 // IDE drive control definitions
00143 //
00144 
00145 #define IDE_DC_DISABLE_INTERRUPTS    0x02
00146 #define IDE_DC_RESET_CONTROLLER      0x04
00147 #define IDE_DC_REENABLE_CONTROLLER   0x00
00148 
00149 //
00150 // IDE error definitions
00151 //
00152 
00153 #define IDE_ERROR_BAD_BLOCK          0x80
00154 #define IDE_ERROR_DATA_ERROR         0x40
00155 #define IDE_ERROR_MEDIA_CHANGE       0x20
00156 #define IDE_ERROR_ID_NOT_FOUND       0x10
00157 #define IDE_ERROR_MEDIA_CHANGE_REQ   0x08
00158 #define IDE_ERROR_COMMAND_ABORTED    0x04
00159 #define IDE_ERROR_END_OF_MEDIA       0x02
00160 #define IDE_ERROR_ILLEGAL_LENGTH     0x01
00161 
00162 //
00163 // ATAPI register definition
00164 //
00165 
00166 typedef struct _ATAPI_REGISTERS_1 {
00167     USHORT Data;
00168     UCHAR InterruptReason;
00169     UCHAR Unused1;
00170     UCHAR ByteCountLow;
00171     UCHAR ByteCountHigh;
00172     UCHAR DriveSelect;
00173     UCHAR Command;
00174 } ATAPI_REGISTERS_1, *PATAPI_REGISTERS_1;
00175 
00176 typedef struct _ATAPI_REGISTERS_2 {
00177     UCHAR AlternateStatus;
00178     UCHAR DriveAddress;
00179 } ATAPI_REGISTERS_2, *PATAPI_REGISTERS_2;
00180 
00181 //
00182 // ATAPI interrupt reasons
00183 //
00184 
00185 #define ATAPI_IR_COD 0x01
00186 #define ATAPI_IR_IO  0x02
00187 
00188 //
00189 // IDENTIFY data
00190 //
00191 
00192 typedef struct _IDENTIFY_DATA {
00193     USHORT GeneralConfiguration;            // 00 00
00194     USHORT NumberOfCylinders;               // 02  1
00195     USHORT Reserved1;                       // 04  2
00196     USHORT NumberOfHeads;                   // 06  3
00197     USHORT UnformattedBytesPerTrack;        // 08  4
00198     USHORT UnformattedBytesPerSector;       // 0A  5
00199     USHORT SectorsPerTrack;                 // 0C  6
00200     USHORT VendorUnique1[3];                // 0E  7-9
00201     USHORT SerialNumber[10];                // 14  10-19
00202     USHORT BufferType;                      // 28  20
00203     USHORT BufferSectorSize;                // 2A  21
00204     USHORT NumberOfEccBytes;                // 2C  22
00205     USHORT FirmwareRevision[4];             // 2E  23-26
00206     USHORT ModelNumber[20];                 // 36  27-46
00207     UCHAR  MaximumBlockTransfer;            // 5E  47
00208     UCHAR  VendorUnique2;                   // 5F
00209     USHORT DoubleWordIo;                    // 60  48
00210     USHORT Capabilities;                    // 62  49
00211     USHORT Reserved2;                       // 64  50
00212     UCHAR  VendorUnique3;                   // 66  51
00213     UCHAR  PioCycleTimingMode;              // 67
00214     UCHAR  VendorUnique4;                   // 68  52
00215     UCHAR  DmaCycleTimingMode;              // 69
00216     USHORT TranslationFieldsValid:1;        // 6A  53
00217     USHORT Reserved3:15;
00218     USHORT NumberOfCurrentCylinders;        // 6C  54
00219     USHORT NumberOfCurrentHeads;            // 6E  55
00220     USHORT CurrentSectorsPerTrack;          // 70  56
00221     ULONG  CurrentSectorCapacity;           // 72  57-58
00222     USHORT CurrentMultiSectorSetting;       //     59
00223     ULONG  UserAddressableSectors;          //     60-61
00224     USHORT SingleWordDMASupport : 8;        //     62
00225     USHORT SingleWordDMAActive : 8;
00226     USHORT MultiWordDMASupport : 8;         //     63
00227     USHORT MultiWordDMAActive : 8;
00228     USHORT AdvancedPIOModes : 8;            //     64
00229     USHORT Reserved4 : 8;
00230     USHORT MinimumMWXferCycleTime;          //     65
00231     USHORT RecommendedMWXferCycleTime;      //     66
00232     USHORT MinimumPIOCycleTime;             //     67
00233     USHORT MinimumPIOCycleTimeIORDY;        //     68
00234     USHORT Reserved5[2];                    //     69-70
00235     USHORT ReleaseTimeOverlapped;           //     71
00236     USHORT ReleaseTimeServiceCommand;       //     72
00237     USHORT MajorRevision;                   //     73
00238     USHORT MinorRevision;                   //     74
00239     USHORT Reserved6[50];                   //     75-126
00240     USHORT SpecialFunctionsEnabled;         //     127
00241     USHORT Reserved7[128];                  //     128-255
00242 } IDENTIFY_DATA, *PIDENTIFY_DATA;
00243 
00244 //
00245 // Identify data without the Reserved4.
00246 //
00247 
00248 typedef struct _IDENTIFY_DATA2 {
00249     USHORT GeneralConfiguration;            // 00
00250     USHORT NumberOfCylinders;               // 02
00251     USHORT Reserved1;                       // 04
00252     USHORT NumberOfHeads;                   // 06
00253     USHORT UnformattedBytesPerTrack;        // 08
00254     USHORT UnformattedBytesPerSector;       // 0A
00255     USHORT SectorsPerTrack;                 // 0C
00256     USHORT VendorUnique1[3];                // 0E
00257     USHORT SerialNumber[10];                // 14
00258     USHORT BufferType;                      // 28
00259     USHORT BufferSectorSize;                // 2A
00260     USHORT NumberOfEccBytes;                // 2C
00261     USHORT FirmwareRevision[4];             // 2E
00262     USHORT ModelNumber[20];                 // 36
00263     UCHAR  MaximumBlockTransfer;            // 5E
00264     UCHAR  VendorUnique2;                   // 5F
00265     USHORT DoubleWordIo;                    // 60
00266     USHORT Capabilities;                    // 62
00267     USHORT Reserved2;                       // 64
00268     UCHAR  VendorUnique3;                   // 66
00269     UCHAR  PioCycleTimingMode;              // 67
00270     UCHAR  VendorUnique4;                   // 68
00271     UCHAR  DmaCycleTimingMode;              // 69
00272     USHORT TranslationFieldsValid:1;        // 6A
00273     USHORT Reserved3:15;
00274     USHORT NumberOfCurrentCylinders;        // 6C
00275     USHORT NumberOfCurrentHeads;            // 6E
00276     USHORT CurrentSectorsPerTrack;          // 70
00277     ULONG  CurrentSectorCapacity;           // 72
00278 } IDENTIFY_DATA2, *PIDENTIFY_DATA2;
00279 
00280 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA)
00281 
00282 //
00283 // IDENTIFY capability bit definitions.
00284 //
00285 
00286 #define IDENTIFY_CAPABILITIES_DMA_SUPPORTED 0x0100
00287 #define IDENTIFY_CAPABILITIES_LBA_SUPPORTED 0x0200
00288 
00289 //
00290 // IDENTIFY DMA timing cycle modes.
00291 //
00292 
00293 #define IDENTIFY_DMA_CYCLES_MODE_0 0x00
00294 #define IDENTIFY_DMA_CYCLES_MODE_1 0x01
00295 #define IDENTIFY_DMA_CYCLES_MODE_2 0x02
00296 
00297 
00298 typedef struct _BROKEN_CONTROLLER_INFORMATION {
00299     PCHAR   VendorId;
00300     ULONG   VendorIdLength;
00301     PCHAR   DeviceId;
00302     ULONG   DeviceIdLength;
00303 }BROKEN_CONTROLLER_INFORMATION, *PBROKEN_CONTROLLER_INFORMATION;
00304 
00305 BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[] = {
00306     { "1095", 4, "0640", 4},
00307     { "1039", 4, "0601", 4}
00308 };
00309 
00310 #define BROKEN_ADAPTERS (sizeof(BrokenAdapters) / sizeof(BROKEN_CONTROLLER_INFORMATION))
00311 
00312 typedef struct _NATIVE_MODE_CONTROLLER_INFORMATION {
00313     PCHAR   VendorId;
00314     ULONG   VendorIdLength;
00315     PCHAR   DeviceId;
00316     ULONG   DeviceIdLength;
00317 }NATIVE_MODE_CONTROLLER_INFORMATION, *PNATIVE_MODE_CONTROLLER_INFORMATION;
00318 
00319 NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = {
00320     { "10ad", 4, "0105", 4}
00321 };
00322 #define NUM_NATIVE_MODE_ADAPTERS (sizeof(NativeModeAdapters) / sizeof(NATIVE_MODE_CONTROLLER_INFORMATION))
00323 
00324 //
00325 // Beautification macros
00326 //
00327 
00328 #define GetStatus(BaseIoAddress, Status) \
00329     Status = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus);
00330 
00331 #define GetBaseStatus(BaseIoAddress, Status) \
00332     Status = ScsiPortReadPortUchar(&BaseIoAddress->Command);
00333 
00334 #define WriteCommand(BaseIoAddress, Command) \
00335     ScsiPortWritePortUchar(&BaseIoAddress->Command, Command);
00336 
00337 
00338 
00339 #define ReadBuffer(BaseIoAddress, Buffer, Count) \
00340     ScsiPortReadPortBufferUshort(&BaseIoAddress->Data, \
00341                                  Buffer, \
00342                                  Count);
00343 
00344 #define WriteBuffer(BaseIoAddress, Buffer, Count) \
00345     ScsiPortWritePortBufferUshort(&BaseIoAddress->Data, \
00346                                   Buffer, \
00347                                   Count);
00348 
00349 #define ReadBuffer2(BaseIoAddress, Buffer, Count) \
00350     ScsiPortReadPortBufferUlong(&BaseIoAddress->Data, \
00351                              Buffer, \
00352                              Count);
00353 
00354 #define WriteBuffer2(BaseIoAddress, Buffer, Count) \
00355     ScsiPortWritePortBufferUlong(&BaseIoAddress->Data, \
00356                               Buffer, \
00357                               Count);
00358 
00359 #define WaitOnBusy(BaseIoAddress, Status) \
00360 { \
00361     ULONG i; \
00362     for (i=0; i<20000; i++) { \
00363         GetStatus(BaseIoAddress, Status); \
00364         if (Status & IDE_STATUS_BUSY) { \
00365             ScsiPortStallExecution(150); \
00366             continue; \
00367         } else { \
00368             break; \
00369         } \
00370     } \
00371 }
00372 
00373 #define WaitOnBaseBusy(BaseIoAddress, Status) \
00374 { \
00375     ULONG i; \
00376     for (i=0; i<20000; i++) { \
00377         GetBaseStatus(BaseIoAddress, Status); \
00378         if (Status & IDE_STATUS_BUSY) { \
00379             ScsiPortStallExecution(150); \
00380             continue; \
00381         } else { \
00382             break; \
00383         } \
00384     } \
00385 }
00386 
00387 #define WaitForDrq(BaseIoAddress, Status) \
00388 { \
00389     ULONG i; \
00390     for (i=0; i<1000; i++) { \
00391         GetStatus(BaseIoAddress, Status); \
00392         if (Status & IDE_STATUS_BUSY) { \
00393             ScsiPortStallExecution(100); \
00394         } else if (Status & IDE_STATUS_DRQ) { \
00395             break; \
00396         } else { \
00397             ScsiPortStallExecution(200); \
00398         } \
00399     } \
00400 }
00401 
00402 
00403 #define WaitShortForDrq(BaseIoAddress, Status) \
00404 { \
00405     ULONG i; \
00406     for (i=0; i<2; i++) { \
00407         GetStatus(BaseIoAddress, Status); \
00408         if (Status & IDE_STATUS_BUSY) { \
00409             ScsiPortStallExecution(100); \
00410         } else if (Status & IDE_STATUS_DRQ) { \
00411             break; \
00412         } else { \
00413             ScsiPortStallExecution(100); \
00414         } \
00415     } \
00416 }
00417 
00418 #define AtapiSoftReset(BaseIoAddress,DeviceNumber) \
00419 {\
00420     UCHAR statusByte; \
00421     ULONG i = 1000*1000;\
00422     ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)(((DeviceNumber & 0x1) << 4) | 0xA0)); \
00423     ScsiPortStallExecution(500);\
00424     ScsiPortWritePortUchar(&BaseIoAddress->Command, IDE_COMMAND_ATAPI_RESET); \
00425     while ((ScsiPortReadPortUchar(&BaseIoAddress->Command) & IDE_STATUS_BUSY) && i--)\
00426         ScsiPortStallExecution(30);\
00427     ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)((DeviceNumber << 4) | 0xA0)); \
00428     WaitOnBusy( ((PIDE_REGISTERS_2)((PUCHAR)BaseIoAddress + 0x206)), statusByte); \
00429     ScsiPortStallExecution(500);\
00430 }
00431 
00432 #define IdeHardReset(BaseIoAddress,result) \
00433 {\
00434     UCHAR statusByte;\
00435     ULONG i;\
00436     ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_RESET_CONTROLLER );\
00437     ScsiPortStallExecution(50 * 1000);\
00438     ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_REENABLE_CONTROLLER);\
00439     for (i = 0; i < 1000 * 1000; i++) {\
00440         statusByte = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus);\
00441         if (statusByte != IDE_STATUS_IDLE && statusByte != 0x0) {\
00442             ScsiPortStallExecution(5);\
00443         } else {\
00444             break;\
00445         }\
00446     }\
00447     if (i == 1000*1000) {\
00448         result = FALSE;\
00449     }\
00450     result = TRUE;\
00451 }
00452 
00453 #define IS_RDP(OperationCode)\
00454     ((OperationCode == SCSIOP_ERASE)||\
00455     (OperationCode == SCSIOP_LOAD_UNLOAD)||\
00456     (OperationCode == SCSIOP_LOCATE)||\
00457     (OperationCode == SCSIOP_REWIND) ||\
00458     (OperationCode == SCSIOP_SPACE)||\
00459     (OperationCode == SCSIOP_SEEK)||\
00460     (OperationCode == SCSIOP_WRITE_FILEMARKS))
00461 

Generated on Thu May 24 2012 04:28:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.